CGI/Perl Guide | Learning Center | Forums | Advertise | Login
Site Search: in

  Main Index MAIN
INDEX
Search Posts SEARCH
POSTS
Who's Online WHO'S
ONLINE
Log in LOG
IN

Home: Perl Programming Help: Regular Expressions:
Can I do an if-then-else regex mixing match and substitution?

 



poly4life
Novice

Mar 25, 2011, 1:46 PM

Post #1 of 7 (5945 views)
Can I do an if-then-else regex mixing match and substitution? Can't Post

Hello,

Is it possible to do mix match and substitution regex's inside an if-then-else regex conditional?

example:

(?(match)s/pattern/replacement/g)

It's not even pseudo-code, just a concept of what I think it might look like, but is this possible?

FYI, I'm searching..matching in a text file. If the text file matches the pattern, then do a search..replace in another area of the text file.

Thank you.


(This post was edited by poly4life on Mar 25, 2011, 1:51 PM)


FishMonger
Veteran / Moderator

Mar 25, 2011, 1:56 PM

Post #2 of 7 (5939 views)
Re: [poly4life] Can I do an if-then-else regex mixing match and substitution? [In reply to] Can't Post

The description of what you want to do is not veery clear, but maybe what you're looking for is zero width assertions.

http://perldoc.perl.org/perlreref.html#EXTENDED-CONSTRUCTS

If not, then provide more details.


miller
User

Mar 25, 2011, 2:11 PM

Post #3 of 7 (5936 views)
Re: [poly4life] Can I do an if-then-else regex mixing match and substitution? [In reply to] Can't Post

Yes, such things are possible, but it's almost certainly better to just break up your logic instead of trying to make a complicated regex.

If you have sample data and conditions we probably could advise you better.

- Miller


poly4life
Novice

Mar 25, 2011, 2:11 PM

Post #4 of 7 (5936 views)
Re: [FishMonger] Can I do an if-then-else regex mixing match and substitution? [In reply to] Can't Post

Yes, I believe those if-then-else conditionals. But it appears, and I could be wrong, that it applies for match regex, not any other type of regex. I want to integrate both match and substitution regex with these conditionals.

see this link: http://www.regular-expressions.info/conditional.html

Normally, I believe it's just "if" this matches, "then" check if that matches, "else" check if yet-another-thing matches.

I have a text file, right.


Code
Hello World 


Foo
Bar


I want to do a search..match on 'Foo'. If it finds 'Foo' in this file, then do a search..replace on 'Hello World'. If it finds 'Hello World', then substitute 'Hello World' for 'Hello Earth'. You see what I mean? If 'Foo' was not present in this text file, it wouldn't even bother looking for 'Hello World'.

Could I do this in a script like Perl? Sure, I could. But I understand Regex provides some sort of condtional functionality and I thought why not just use regex if it has this feature.

Thank you.


FishMonger
Veteran / Moderator

Mar 25, 2011, 2:53 PM

Post #5 of 7 (5931 views)
Re: [poly4life] Can I do an if-then-else regex mixing match and substitution? [In reply to] Can't Post

Is this what you're after?


Code
use warnings; 
use strict;
use File::Slurp;

my $data = read_file('test.txt');

if ( $data =~ /Foo/ ) {
$data =~ s/Hello World/Hello Earth/;
print $data;
}
else {
print "Foo not found\n";
}


You can also do the substitution in the conditional test.

Code
if ( $data =~ /Foo/ and $data =~ s/Hello World/Hello Earth/ ) { 
print $data;
}



(This post was edited by FishMonger on Mar 25, 2011, 2:57 PM)


miller
User

Mar 25, 2011, 3:52 PM

Post #6 of 7 (5927 views)
Re: [poly4life] Can I do an if-then-else regex mixing match and substitution? [In reply to] Can't Post

Follow Fishmongers advice. Doing that in a single regex is possible, but messy.


Code
use warnings;  
use strict;
use File::Slurp;

my $data = read_file('test.txt');

if ( $data =~ /^(?=.*Foo)(.*?)Hello World/${1}Hello Earth/) {
print $data;
} else {
print "Foo not found\n";
}



poly4life
Novice

Mar 28, 2011, 8:41 AM

Post #7 of 7 (5909 views)
Re: [FishMonger] Can I do an if-then-else regex mixing match and substitution? [In reply to] Can't Post

Thank you for the suggestions.

miller's suggestion is pretty much what I was trying to accomplish.

However, I am executing this in in-place edit mode in a batch file and it's failing on the vertical bar character in my regex:


Code
if (m~[\'|\"]\d{1,2}[\'|\"]~i)...


The error is "The system cannot find the path specified."

I realize that I don't need the vertical bar character, in this case, but if I do in the future, this could be an issue. Now, I tried modifying it a couple of different ways to narrow in on the problem.

These work:

Code
if (m~[\'\"]\d{1,2}[\'\"]~i)...


Code
if (m~[\'|\"]\d{1,2}[\'\"]~i)...


This does not:

Code
if (m~[\'\"]\d{1,2}[\'|\"]~i)...


I tried escaping the vertical bar but I got the same error:

Code
if (m~[\'\"]\d{1,2}[\'\|\"]~i)...


Does anybody know what's the problem?

Update: I did manage to find the solution. The problem is I had to precede the vertical bar with the caret (^) symbol and now it enters the if loop, due to the fact that i'm executing a Perl script inside a batch file.

I also discovered that doing a match, followed by a substitution using in-place edit mode won't replace in the file. I think this is also due to the batch process. FYI, I'm using


Code
for %%X in (*.txt) do perl -pi.bak -e "Perl code" %%X


What I'm wondering is is it possible to use look-ahead or look-behind assertions in substitutions or are assertions for matching only? Either way, it appears that in-place edit won't work here and I'll have to follow your suggestions to a T, running separate perl script.

Thank you for your help.


Thank you.


(This post was edited by poly4life on Mar 28, 2011, 9:34 AM)

 
 


Search for (options) Powered by Gossamer Forum v.1.2.0

Web Applications & Managed Hosting Powered by Gossamer Threads
Visit our Mailing List Archives