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: Beginner:
capture substring with known prefix in middle of string

 



KERNELKLINK
Novice

Dec 11, 2013, 6:10 AM

Post #1 of 18 (1618 views)
capture substring with known prefix in middle of string Can't Post

so I'm using a regex to capture a substring in the middle of a string with a known format. The substring has the prefix "ABC".

Here's what I've been trying to do, with no luck:

if($line =~ m/insert_pack:(\s*ABC.*)pack_type:/)

$var = $1

-----------------------------

I'm basically trying to capture a substring with the prefix "ABC" in the middle of a string that will look like this:

insert_pack: ABChello pack_type: b

there could be spaces before the "ABC"-prefixed substring as in the example above, so my regex has to capture that too.

The problem is that I'm not catching the substring in $1, so my regex is wrong. Anyone know what the correct syntax would be?


FishMonger
Veteran / Moderator

Dec 11, 2013, 6:21 AM

Post #2 of 18 (1613 views)
Re: [KERNELKLINK] capture substring with known prefix in middle of string [In reply to] Can't Post

Your regex works for me.

Code
use Data::Dumper; 

$line = 'insert_pack: ABChello pack_type: b';

if($line =~ m/insert_pack:(\s*ABC.*)pack_type:/) {
print Dumper $1;
}



Code
c:\test>type perl-1.pl 
use Data::Dumper;

$line = 'insert_pack: ABChello pack_type: b';

if($line =~ m/insert_pack:(\s*ABC.*)pack_type:/) {
print Dumper $1;
}

c:\test>perl-1.pl
$VAR1 = ' ABChello ';



KERNELKLINK
Novice

Dec 11, 2013, 6:37 AM

Post #3 of 18 (1611 views)
Re: [FishMonger] capture substring with known prefix in middle of string [In reply to] Can't Post

try it with this string:

insert_pack:ABChello job_type:b

for some reason it doesn't work with no space between 'insert_pack:' and 'ABChello'


KERNELKLINK
Novice

Dec 11, 2013, 6:44 AM

Post #4 of 18 (1604 views)
Re: [KERNELKLINK] capture substring with known prefix in middle of string [In reply to] Can't Post

sorry, try it with this string:

insert_pack:ABChello pack_type:b

my regex doesn't capture ABChello without a space between 'insert_pack' and 'ABChello'


FishMonger
Veteran / Moderator

Dec 11, 2013, 6:48 AM

Post #5 of 18 (1603 views)
Re: [KERNELKLINK] capture substring with known prefix in middle of string [In reply to] Can't Post

That fails to match because job_type is not the same as pack_type


FishMonger
Veteran / Moderator

Dec 11, 2013, 6:51 AM

Post #6 of 18 (1602 views)
Re: [KERNELKLINK] capture substring with known prefix in middle of string [In reply to] Can't Post


Code
c:\test>type perl-1.pl 
use Data::Dumper;

$line = 'insert_pack:ABChello pack_type:b';

if($line =~ m/insert_pack:(\s*ABC.*)pack_type:/) {
print Dumper $1;
}


Code
c:\test>perl-1.pl 
$VAR1 = 'ABChello ';



KERNELKLINK
Novice

Dec 11, 2013, 7:05 AM

Post #7 of 18 (1598 views)
Re: [FishMonger] capture substring with known prefix in middle of string [In reply to] Can't Post

I have no idea why this code is working for you, but not for me.

Any ideas?


Zhris
Enthusiast

Dec 11, 2013, 7:07 AM

Post #8 of 18 (1593 views)
Re: [KERNELKLINK] capture substring with known prefix in middle of string [In reply to] Can't Post


Quote
I'm basically trying to capture a substring with the prefix "ABC" in the middle of a string


Perhaps a more generic regex is what you are looking for:

http://codepad.org/fD1dAfAa

Code
my $regex = qr/(ABC\w+)/; 
$/ = "\r\n";
$\ = "\n";

$_ =~ $regex and print $1 while ( <DATA> );

__DATA__
insert_pack: ABChello_1 pack_type: b
insert_pack:ABChello_2 job_type:b
insert_pack:ABChello_3 pack_type:b
ABChello_4 test_type
DEFhello_5


Chris


(This post was edited by Zhris on Dec 11, 2013, 7:12 AM)


FishMonger
Veteran / Moderator

Dec 11, 2013, 7:12 AM

Post #9 of 18 (1589 views)
Re: [KERNELKLINK] capture substring with known prefix in middle of string [In reply to] Can't Post


In Reply To
I have no idea why this code is working for you, but not for me.

Any ideas?


My guess is that the code you're actually executing is not the same as what you've posted.

Please post a short but complete script that demonstrates the problem and we'll explain why it's failing.


KERNELKLINK
Novice

Dec 11, 2013, 7:17 AM

Post #10 of 18 (1584 views)
Re: [FishMonger] capture substring with known prefix in middle of string [In reply to] Can't Post

foreach $line (<STDIN>)
{
print $bob;
if($line =~ /insert_pack: /)
{

$com = '_113';
if($line =~ m/insert_pack:(\s*ABC.*)pack_type:/) {
$pack_name = $1;
$insert_pack = $1;
$insert_pack =~ s/^\s+|\s+$//g; #remove leading and trailing whitespace
$insert_pack = $insert_pack . $com;
$mod = " " . $insert_pack . " ";
$line =~ s/$pack_name/$mod/g;
$bob = $line . "\n";
}


}
$bob = $line . "\n";

}


print $bob;



---------------------------------------



input:

perl myscript.pl < test.txt

test.txt:

insert_pack:ABChello pack_type:b



My intent with the script is to read test.txt from STDIN and output to STDOUT:

'insert_pack: ABChello_113 pack_type:b'


FishMonger
Veteran / Moderator

Dec 11, 2013, 7:43 AM

Post #11 of 18 (1574 views)
Re: [KERNELKLINK] capture substring with known prefix in middle of string [In reply to] Can't Post

The regex in the first conditional is requiring a space after insert_pack: but the line you're passing to the script doesn't have that required space.

EVERY Perl script you write should start out with 2 pragmas after the shebang line.

Code
$!/usr/bin/perl 

use strict;
use warnings;


The strict pragma will require you to declare your vars, which is done with the my keyword.
e.g.,

Code
foreach my $line (<STDIN>)


You should add those pragmas to your script and fix all of the problems that they point out.


KERNELKLINK
Novice

Dec 11, 2013, 8:24 AM

Post #12 of 18 (1568 views)
Re: [FishMonger] capture substring with known prefix in middle of string [In reply to] Can't Post

Thanks for the feedback.

So how do I write the first conditional so that it matches 'ABChello' with zero or more spaces after 'insert_pack:' and between 'ABChello'?

I thought that (\s*ABC.*) should do the trick, but apparently not.

Sorry, I am totally new to Perl. Just kind of cobbled this script together, haphazardly. I'm a Java programmer :-P


FishMonger
Veteran / Moderator

Dec 11, 2013, 8:42 AM

Post #13 of 18 (1558 views)
Re: [KERNELKLINK] capture substring with known prefix in middle of string [In reply to] Can't Post


Quote
I thought that (\s*ABC.*) should do the trick, but apparently not.


That is in your second regex. I'm referring to the prior one (which is not even needed).

Code
if($line =~ /insert_pack: /)


I need to take a closer look at your code to be sure, but I suspect that it could be reduced to 2 or 3 lines.


KERNELKLINK
Novice

Dec 11, 2013, 8:45 AM

Post #14 of 18 (1556 views)
Re: [FishMonger] capture substring with known prefix in middle of string [In reply to] Can't Post

The reason I included the first conditional is because there is other data in the file, but I only want to inspect lines that begin with 'insert_pack', so please focus on the second conditional because that is the problem. I only need to know how to capture 'ABChello' with or without spaces between it and 'insert_pack:'. Thank you for helping me.


FishMonger
Veteran / Moderator

Dec 11, 2013, 9:02 AM

Post #15 of 18 (1551 views)
Re: [KERNELKLINK] capture substring with known prefix in middle of string [In reply to] Can't Post

The first conditional IS the source of the problem. Because of that conditional, the code in that block is not being executed so the second conditional never comes into play.

There are a number of other issues with the code, but for now I'll focus on that first conditional by simply commenting it out.


Code
foreach $line (<STDIN>) { 
print $bob;
#if ( $line =~ /insert_pack: / ) {

$com = '_113';
if ( $line =~ m/insert_pack:(\s*ABC.*)pack_type:/ ) {
$pack_name = $1;
$insert_pack = $1;
$insert_pack =~
s/^\s+|\s+$//g; #remove leading and trailing whitespace
$insert_pack = $insert_pack . $com;
$mod = " " . $insert_pack . " ";
$line =~ s/$pack_name/$mod/g;
$bob = $line . "\n";
}

#}
$bob = $line . "\n";

}

print $bob;


c:\test>KERNELKLINK.pl < test.txt
insert_pack: ABChello_113 pack_type:b


KERNELKLINK
Novice

Dec 11, 2013, 9:30 AM

Post #16 of 18 (1547 views)
Re: [FishMonger] capture substring with known prefix in middle of string [In reply to] Can't Post

It's working. Apparently I was saving the file I was working on to a different directory than the one in which I was executing an old copy of the same file. D'oh! lol. Thanks for your help anyway!



I have another question:



foreach $line (<STDIN>)
{
print $bob;

$com = '^XYZ';
if($line =~ m/.*(\^ABC).*/) {
$pack_name = $1;
$line =~ s/$pack_name/$com/g;
$bob = $line . "\n";
}


$bob = $line . "\n";

}


print $bob;



----------



The input looks like this:

comptroll: t(hello^ABC) or t(sometext)......

I am trying to capture the '^ABC' and replace it with '^XYZ'

I am able to catpure the '^ABC', but I the replace isn't working. I know I am capturing '^ABC' because I printed out $1 while debugging.

Can you please tell me what is wrong with my replace statement (i.e. $line =~ s/$pack_name/$com/g; ). Or maybe there is something else I need to do in the script?


BillKSmith
Veteran

Dec 11, 2013, 11:50 AM

Post #17 of 18 (1530 views)
Re: [KERNELKLINK] capture substring with known prefix in middle of string [In reply to] Can't Post

Perl's regex engine thinks the caret character in your string in the metacharacter "start-of-string" unless you find some way to escape it.


Code
$line =~ s/\Q$pack_name\E/$com/g;

Good Luck,
Bill


FishMonger
Veteran / Moderator

Dec 11, 2013, 11:54 AM

Post #18 of 18 (1529 views)
Re: [KERNELKLINK] capture substring with known prefix in middle of string [In reply to] Can't Post

Bill has answered why your code was failing.

Now, here's a cleaner and more efficient way to do it.


Code
foreach my $line (<STDIN>) 
{
$line =~ s/\^ABC/^XYZ/;
print $line;
}


Which could be reduced to a one liner.
c:\test>perl -pe "s/\^ABC/^XYZ/" test.txt


(This post was edited by FishMonger on Dec 11, 2013, 11:56 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