reg exp: helping hand needed

O

Oliver Meister

Hello all

I might ask a quite trivial question but I don't get any further -
please excuse.

The following content is held in a string "$SingleMessage".
---------------------------------------------
1035 Zxxxxxxx
2317 XXXXXXXXXXXXXXXXXXXX
940 02
:20:XXXXXX202
:25:XXX25XXXXXXXXXXXX
:28:XXXXXXXXXXXXXXXXXXXX1
X XXXXXXXXXX XX XXXXXX X XXXXXXXXXX XX XXXXXX
X XXXXXXXXXX XX XXXXXX
:60F:XXXXXXXXXXXXXXXXXXXX1
:62F:XXXX222XXXXXXXXXXX
XXXX222XXXXXXXXXXX XXXXXXXXXX XX XXXXXX
:64:XXXXXXXXXXXXXXXXXXXX
---------------------------------------------

I'd like to receive the value, where ":<nn>:" is the field seperator
and "xxxx" the value, until the next field.
In other words: I'd like to return the values in between two
seperators, selected by a seperator.

I was trying with $fld_28 =~ s/:)28:)(.*?)/$1/ ; print $1;
This prints ":28:" only ...

I guess, that the s/ option isn't suitable (?).

May somebody lend me a helping hand?

Regards,
Oliver
 
P

Paul Lalli

Oliver said:
I might ask a quite trivial question but I don't get any further -
please excuse.

The following content is held in a string "$SingleMessage".
---------------------------------------------
1035 Zxxxxxxx
2317 XXXXXXXXXXXXXXXXXXXX
940 02
:20:XXXXXX202
:25:XXX25XXXXXXXXXXXX
:28:XXXXXXXXXXXXXXXXXXXX1
X XXXXXXXXXX XX XXXXXX X XXXXXXXXXX XX XXXXXX
X XXXXXXXXXX XX XXXXXX
:60F:XXXXXXXXXXXXXXXXXXXX1
:62F:XXXX222XXXXXXXXXXX
XXXX222XXXXXXXXXXX XXXXXXXXXX XX XXXXXX
:64:XXXXXXXXXXXXXXXXXXXX

I think you mean that a "separator" is a colon, two digits, and another
colon. Okay, but what about ":60F:" and ":62F:" ? Are those
separators too? They don't match your description.
and "xxxx" the value, until the next field.
In other words: I'd like to return the values in between two
seperators, selected by a seperator.

I was trying with $fld_28 =~ s/:)28:)(.*?)/$1/ ; print $1;
This prints ":28:" only ...

Of course it does. What were you expecting that to do? You searched
for ":28:" (saving it in $1), followed by the fewest number of
any-character (except the newline) that could be found. That of
course, is 0, so $2 is the empty string. Then you replaced everything
you matched - which, again, was only ":28:" - with whatever was in $1,
which was ":28:". So the string doesn't change at all, and $1 is
printed out after the s///. No idea what made you think that would do
anything else.
I guess, that the s/ option isn't suitable (?).

I have no idea what that means. Are you talking about the s///
operator, or the /s option? The s/// operator is for modifying a
string. So no, you don't want to use that. You just want to pattern
match, ie, the m// operator. The /s option allows the . wildcard to
match newlines, so yes you do want that.

You want to match all the characters, including newlines, that exist
between ":28:" and the next insance of colon, two digits, colon. So do
that:

if ($fld_28 =~ /:28:(.*?):\d{2}:/){
print "Value: $1";
}

Paul Lalli
 
P

Paul Lalli

Oliver said:
I might ask a quite trivial question but I don't get any further -
please excuse.

The following content is held in a string "$SingleMessage".
---------------------------------------------
1035 Zxxxxxxx
2317 XXXXXXXXXXXXXXXXXXXX
940 02
:20:XXXXXX202
:25:XXX25XXXXXXXXXXXX
:28:XXXXXXXXXXXXXXXXXXXX1
X XXXXXXXXXX XX XXXXXX X XXXXXXXXXX XX XXXXXX
X XXXXXXXXXX XX XXXXXX
:60F:XXXXXXXXXXXXXXXXXXXX1
:62F:XXXX222XXXXXXXXXXX
XXXX222XXXXXXXXXXX XXXXXXXXXX XX XXXXXX
:64:XXXXXXXXXXXXXXXXXXXX

I think you mean that a "separator" is a colon, two digits, and another
colon. Okay, but what about ":60F:" and ":62F:" ? Are those
separators too? They don't match your description.
and "xxxx" the value, until the next field.
In other words: I'd like to return the values in between two
seperators, selected by a seperator.

I was trying with $fld_28 =~ s/:)28:)(.*?)/$1/ ; print $1;
This prints ":28:" only ...

Of course it does. What were you expecting that to do? You searched
for ":28:" (saving it in $1), followed by the fewest number of
any-character (except the newline) that could be found. That of
course, is 0, so $2 is the empty string. Then you replaced everything
you matched - which, again, was only ":28:" - with whatever was in $1,
which was ":28:". So the string doesn't change at all, and $1 is
printed out after the s///. No idea what made you think that would do
anything else.
I guess, that the s/ option isn't suitable (?).

I have no idea what that means. Are you talking about the s///
operator, or the /s option? The s/// operator is for modifying a
string. So no, you don't want to use that. You just want to pattern
match, ie, the m// operator. The /s option allows the . wildcard to
match newlines, so yes you do want that.

You want to match all the characters, including newlines, that exist
between ":28:" and the next insance of colon, two digits, colon. So do
that:

if ($fld_28 =~ /:28:(.*?):\d{2}:/s){
print "Value: $1";
}

Paul Lalli
 
G

Gunnar Hjalmarsson

Oliver said:
The following content is held in a string "$SingleMessage".
---------------------------------------------
1035 Zxxxxxxx
2317 XXXXXXXXXXXXXXXXXXXX
940 02
:20:XXXXXX202
:25:XXX25XXXXXXXXXXXX
:28:XXXXXXXXXXXXXXXXXXXX1
X XXXXXXXXXX XX XXXXXX X XXXXXXXXXX XX XXXXXX
X XXXXXXXXXX XX XXXXXX
:60F:XXXXXXXXXXXXXXXXXXXX1
:62F:XXXX222XXXXXXXXXXX
XXXX222XXXXXXXXXXX XXXXXXXXXX XX XXXXXX
:64:XXXXXXXXXXXXXXXXXXXX
---------------------------------------------

I'd like to receive the value, where ":<nn>:" is the field seperator
and "xxxx" the value, until the next field.
In other words: I'd like to return the values in between two
seperators, selected by a seperator.

Storing the key/value pairs in a hash may or may not be what you want:

my %hash;
while ( $SingleMessage =~ /:(\w+):(.+?)(?=:\w+:|$)/gs ) {
$hash{$1} = $2;
}
 
O

Oliver Meister

Paul said:
Oliver Meister wrote: ....

I think you mean that a "separator" is a colon, two digits, and another
colon. Okay, but what about ":60F:" and ":62F:" ? Are those
separators too? They don't match your description.

True! And yes, they are seperators too.

....
....

you matched - which, again, was only ":28:" - with whatever was in $1,
which was ":28:". So the string doesn't change at all, and $1 is
printed out after the s///. No idea what made you think that would do
anything else.

A Lack of wisdom!

....
You want to match all the characters, including newlines, that exist
between ":28:" and the next insance of colon, two digits, colon. So do
that:

if ($fld_28 =~ /:28:(.*?):\d{2}:/s){
print "Value: $1";
}

Paul Lalli

Thank you. Looking at it now, I SHOULD have figured out on my own. I
was too sure that I need an option like /s or /m....

Well, I'll figure out now (on my own), how I split on a single minus
sign without catching on anything else what includes a minus sign. :)

Thanks,
Oliver
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,055
Latest member
SlimSparkKetoACVReview

Latest Threads

Top