views:

409

answers:

8

can best help me systematically modify the "replace" field of a regex search as it encounters each match.

For example, I have an xml file that needs the phrase "id = $number" inserted at regular points in the text, and basically, $number++ each time the regex matches (id = 1, id = 2, etc) until the end of the file.

I know I could just write a bash/perl/python script or some such, but I'd like it to be at least moderately user-friendly so I could teach my intelligent (but less technically-inclined) workers how to use it and make their own modifications. Regexing is not a problem for them.

The closest I've come so far is Notepad++'s Column Editor and 'increase [number] by' function, but with this I have to write a separate regex to align everything, add the increments, and then write another to put it back. Unfortunately, I need to use this function on too many different types of files and 'replace's to make macros feasible.

Ideally, the program would also be available for both Windows & Linux (WINE is acceptable but native is much preferred), and have a 'VI/VIM input' option (if it's a text editor), but these are of secondary importance.

Of course, it'd be nice if there is an OSS solution, and I'd be glad to donate $20-$50 to the developer(s) if it provides the solution I'm looking for.


Apologies for the length, and thanks so much for your help!

+8  A: 

emacs (version 22 and later) can do what you're looking for. See Steve Yegge's blog for a really interesting read about it. I think this should work:

M-x replace-regexp
  Replace regexp: insert pattern regexp here
  Replace regexp with: id = \#

\# is a special metacharacter that gets replaced by the total number of replacements that have occurred so far, starting from 0. If you want the list to start from 1 instead of 0, use the following replacement string:

id = \,(1+ \#)
Adam Rosenfield
"Oh yeah! Good ol' C-x M-c M-butterfly..." http://xkcd.com/378/Original poster here. Thanks so much for your suggestion! Clearly my bias against Emacs has blinded me, but I'll try it out later tonight (downloading it now... arrrrgh!) My only concern is the user-unfriendliness-- fingers crossed!
chameleon3
chameleon3
+2  A: 

JEdit can probably help you: http://www.jedit.org/

you can do all kinds of regex and even bean result based replacing with it.

Zak
Hi, original poster here. Thanks for the suggestion! I use Jedit frequently myself, and the regex is indeed nice, but I'm not aware of any such function with beanshell-- can you or anyone point me in the right direction?
chameleon3
To answer your question: http://www.jedit.org/users-guide/search-replace.html#id2558292
Axeman
yes, I learned about beanshell before both from the link you provided and http://www.jedit.org/users-guide/writing-macros-part.html Unfortunately, I still haven't found a simple solution to the original problem. I hope it exists because Jedit is one of the three editors I use most frequently
chameleon3
A: 

Take a look at UltraEdit32. It's very good. Not free, but available in Windows, Linux and Mac platforms. It has regex based search & replace.

Pablo Santa Cruz
Great minds think alike. :) They do have linux/mac now too tho!
JP Alioto
Cool! Did not know that... It's being a long time since I stopped using UltraEdit32 and switched to Notepad++. But agree with you: UltraEdit32 is a great editor. Going to change my post to reflect Linux/Mac versions now. Thanks!
Pablo Santa Cruz
+1  A: 

UltraEdit32 is great and I believe it has the features you need. There is a free 30-day download so you can make sure. :)

JP Alioto
+1  A: 

I know you want an app available on Windows/Linux, but there's another solution on Mac : TextWrangler, and it's free.

elbaid
TextWrangler is awesome!
Pablo Santa Cruz
Hello, original poster here. Thanks for the suggestion! I've been a fan of BBedit and TextWrangler for years, but again, no one in my laboratory uses a mac :-( Also, I'm unfamiliar with any increment function on Textwrangler... what is it?
chameleon3
A: 

This script should let you do what you want in Vim.

Steve Rowe
Hello, original poster here. Thanks for the suggestion! I have no doubt it'll work as advertised, but unfortunately it's probably way too complicated for my workers :-( I'll definitely file it away for my own use though!
chameleon3
A: 

Vim functions can do the incrementing number trick and aren't too hard to write. For example the Vim wiki says how to do this. See also :h sub-replace-\=.

function! Counter()
    let i = g:c
    let g:c = g:c + 1
    return i
endfunction

:let c=1|%s/<\w\+\zs/\=' id="' . Counter() . '"'/g

We've probably left user-friendliness long behind at this point but Vim's Ruby support can do this kind of thing easily too:

:ruby c=0
:rubydo $_.gsub!(/<\w+/){|m| c += 1; m + ' id="' + c.to_s + '"'}

Or Perl:

:perl $c=1
:perldo s/<\w+/$& . ' id="' . $c++ . '"'/eg
Brian Carper
Hi, original poster here. Thanks for the suggestions! Those all look like they'd do the trick, but I'm just thrilled I've taught them regex and they can launch firefox in KDE. Their job doesn't require serious computer skills, so I think their eyes would glaze over at this :p
chameleon3
A: 

To me, this sounds like it might be a job for awk, rather than a job for an editor.

smcameron
Hi, original poster here. Thanks for the suggestion! I agree that awk/grep/sed would ultimately work nicely, but again, I'm afraid it's a bit too much to ask for my workers.
chameleon3