General Question

joshuav's avatar

I have a text file, and i want to replace P(blah) with P[blah], everywhere that it exists?

Asked by joshuav (17points) July 16th, 2009
13 responses
“Great Question” (0points)

importantly, the “blah” between the paren are often different, and of different lengths. sometimes, they include even other pairs of parens. for instance, i might have something like, P(X(t), Y(t)), and also something like P(X(t)). i would like some code that automatically replaces only the OUTER paren with square brackets. thanks.

Topics: , ,
Observing members: 0
Composing members: 0

Answers

jpasq03's avatar

Hmm…
I can’t think of any special programs at the moment, You could however do a control – F (or command – F) keyboard shortcut and bring up the “find” box.

In another tab there should be an option “Replace”, type the text to find, then the text that will replace it, hit replace (or replace all).

I’m not sure how that would handle different parenthesis’. I’d make a backup, just in case.

cwilbur's avatar

I’d probably write a regular expression to do this.

perl -MRegexp::Common -pi.bak -e ‘s/P\(($RE{balanced}{-parens=>q{()}})\)/P[$1]/g;’ file.txt

This won’t work when the expression is broken across two lines.

lillycoyote's avatar

Maybe try this? http://detagger.software.informer.com/ or search on markup remover or detagger and see what you can find.

joshuav's avatar

cwilbur, yes, the perl script above was exactly what i was looking for. here’s what happened though:

$ perl -MRegexp::Common -pi.bak -e ‘s/P\(($RE{balanced}{-parens=>q{()}})\)/P[$1]/g;’ test.txt
Can’t locate Regexp/Common.pm in @INC (@INC contains: /opt/local/lib/perl5/5.8.8/darwin-2level /opt/local/lib/perl5/5.8.8 /opt/local/lib/perl5/site_perl/5.8.8/darwin-2level /opt/local/lib/perl5/site_perl/5.8.8 /opt/local/lib/perl5/site_perl /opt/local/lib/perl5/vendor_perl/5.8.8/darwin-2level /opt/local/lib/perl5/vendor_perl/5.8.8 /opt/local/lib/perl5/vendor_perl .).
BEGIN failed—compilation aborted.

so, i did a

sudo port install p5-regexp-common

this time, i got no error, but also no change. so, then i created a file called test.txt that contains whose entirety is: P()

running the perl script on that also did nothing. does it work for you? one issue might be that when i copy&paste the above line into terminal (i’m running osx), it replaces the single quotes with ?^?^?. i manually replaced them. can you think of anything? many thanks

cwilbur's avatar

It needed refining. The one I gave you would have matched only if there were doubled parentheses: P(()).

perl -MRegexp::Common -pi.bak -e ‘s/P\(([^()]+$RE{balanced}{-parens=>q{()}}?)[^()]+\)/P[$1]/g;’ file.txt

Replace the two + signs with *s – when I put both in, they boldfaced the bit in between.

joshuav's avatar

interesting. so, the one you gave me first indeed works when i have something like “P(())”, but not “P()” or “P(()())”.

the one above doesn’t seem to do anything though. i tried both:

perl -MRegexp::Common -pi.bak -e ‘s/P\(([^()]+$RE{balanced}{-parens=>q{()}}?)[^()]+\)/P[$1]/g;’ file.txt

and

perl -MRegexp::Common -pi.bak -e ‘s/P\(([^()]*s$RE{balanced}{-parens=>q{()}}?)[^()]*s\)/P[$1]/g;’ file.txt

thoughts?

cwilbur's avatar

I just copied and pasted it myself, and it works as indicated for me. (Substituting stupid quotes for the smart quotes, of course.)

My file had lines like P(), P(foo), and P(Q(A,B)) in it, and it handled all the cases correctly.

joshuav's avatar

interesting. so, i just tried it again, and
perl -MRegexp::Common -pi.bak -e ‘s/P\(([^()]+$RE{balanced}{-parens=>q{()}}?)[^()]+\)/P[$1]/g;’ file.txt

handles all the case i tried nearly correctly, except that it deletes the last character before the last closing ). ie, if i have

P(ab)

i get

P[a]

thoughts?

joshuav's avatar

i guess a simple solution to this problem would be to first go through and add a space before each ’)’, and then use your perl script, and then remove the space before each ’]’ and ’)’. but i’m guessing you have a better solution :)

cwilbur's avatar

ah! When I said “replace the + with *s” I meant replace + with *, not with *s – I was making * plural.

Also, the parenthesis after }}? needs to be after *\) instead.

joshuav's avatar

i see. ok, many thanks for your help! if you care to explain the syntax to me, i’m very curious….

cwilbur's avatar

It’s a lot more than I can explain in a quip. You should look for a book called Mastering Regular Expressions—that’s a good place to start.

joshuav's avatar

will do, many thanks :)

ps – i discovered that using vim, the command:

%s/P(\([^[P\$]]*\))/P[\1]/gc

worked as well. i now understand how that works, since i had a bunch of files i needed to do that with, i opened them all up in different tabs, used “tabdo” and then the above, which also worked! one of these days, i’m going to have to learn how to use perl, regexp, etc….

Answer this question

Login

or

Join

to answer.

Mobile | Desktop


Send Feedback   

`