Complex line parse - need help
Could y开发者_如何学Cou help me to correct my parse code.
constant fixup privite ConfigAlarms = <U1 0> /* comment here*/
Slip of my code below,
I don't know how to get the value of U1
and 0
and **/* comment here*/**
.
if(/^\s*(constant)\s*(fixup|\/\*fixup\*\/|)\s*(private|)\s*(\w+)^ ...(Need help here.)
{
$name1 = $1; # for content
$name2 = $2; # for fixup
$name3 = $3; # for privite
$name4 = $4; # for ConfigALarms
$name5 = $5; # for U1
$name6 = $6; # for 0
$name7 = $7; # for /* comment here*/
Thank you for your guide
Updated the completed code
if(/^\s*(constant)\s*(fixup|\/\*fixup\*\/|)\s*(private|)\s*(\w+)\s+=\s+<([a-zA-Z0-9]+)\s+([0-9]+)>\s*\/\*\s*(.*?)\s*\*\/(\r|\n|\s)/)
Take your input:
constant fixup privite ConfigAlarms = <U1 0> /* comment here*/
And start replacing the variables with regular expressions while leaving the constants alone (also you need to escape Perl stuff):
constant fixup privite (\w+) = <([a-zA-Z0-9]+) ([0-9]+)> \/\* (.*?) \*\/
Then you can make it robust against spaces:
constant\s+fixup\s+privite\s(\w+)\s+=\s+<([a-zA-Z0-9]+)\s+([0-9]+)>\s+\/\*(.*?)\*\/
Your variables are now in $1, $2, and $3.
You have a mismatch between "private" in your regex and "privite" in your data.
After (\w+)
there shouldn't be a ^; instead, you would have
\s*=\s*\<\s*(\S+)\s+(\S+)\s*\>\s*\/\*\s*(.*?)\s*\*\/
or something like that, assuming there are always two things inside the <> and those things can have anything but spaces. If those assumptions are incorrect, you need to provide more information about what your data may look like.
Ouch. First, there is an x
modifier that will allow non-significant whitespace in your expression, so that you can make it more readable:
my $pattern = qr{
^\s*
constant\s*
#etc
}x;
(Notice the x
modifier after the ending curly brace.) Next, as already demonstrated by the previous example, you can pick a delimiting character for the pattern, so that you don’t have to escape slashes in the expression:
my $pattern1 = qr/delimited by slashes/;
my $pattern2 = qr{delimited by curly braces};
And if you want to just group an expression without capturing it into $1
, $2
etc., you can use the (?:…)
construct:
if ('foo bar' =~ /(?:foo)\s*(bar)/) {
say $1; # bar
}
Or, as of Perl 5.10, you can use named captures:
if ('foo bar' =~ /(?<name>foo)\s*bar/) {
say $+{name}; # foo
}
This all should make your regexp much more readable. The main point of your question must have been answered by others by now :)
don't have to get too complicated with regex. what you just need are simple ones.
$string= "constant fixup privite ConfigAlarms = <U1 0> /* comment here*/";
@s = split / = / ,$string;
$s[-1] =~ s/<|>//g; #get rid of the < and >
print $s[-1];
the above will give you
$ perl perl.pl
U1 0 /* comment here*/
you can continue from here, either by splitting again , or using a simple group matching
@ss = split /\s+/ , $s[-1];
print Dumper(@ss);
first 2 element values will be U1 and 0, the rest you can join up (or splice) and will be your comments
精彩评论