Сложный разбор строк - нужна помощь - PullRequest
0 голосов
/ 22 декабря 2009

Не могли бы вы помочь мне исправить мой код разбора.

constant fixup privite ConfigAlarms = <U1 0>         /*  comment here*/

Код моего кода ниже, Я не знаю, как получить значение U1 и 0 и **/* 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*/

Спасибо за ваше руководство

Обновлено заполненный код

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)/)

Ответы [ 4 ]

2 голосов
/ 22 декабря 2009

не должно быть слишком сложным с регулярным выражением. то, что вам просто нужно, это простые.

$string= "constant fixup privite ConfigAlarms = <U1 0>         /*  comment here*/";
@s = split / = / ,$string;
$s[-1] =~ s/<|>//g;  #get rid of the < and >
print $s[-1];

выше, даст вам

$ perl perl.pl
U1 0         /*  comment here*/

Вы можете продолжить отсюда, либо снова разделив, либо используя простое сопоставление групп

@ss = split /\s+/ , $s[-1];
print Dumper(@ss);

первые 2 значения элементов будут U1 и 0, остальные вы можете присоединить (или соединить) и будете вашими комментариями

2 голосов
/ 22 декабря 2009

У вас есть несоответствие между "частным" в вашем регулярном выражении и "приватным" в ваших данных.

После (\w+) не должно быть ^; вместо этого у вас будет

\s*=\s*\<\s*(\S+)\s+(\S+)\s*\>\s*\/\*\s*(.*?)\s*\*\/

или что-то в этом роде, при условии, что внутри <> всегда есть две вещи, и эти вещи могут иметь что угодно, кроме пробелов. Если эти предположения неверны, вам необходимо предоставить дополнительную информацию о том, как могут выглядеть ваши данные.

2 голосов
/ 22 декабря 2009

Уч. Во-первых, есть модификатор x, который допустит незначительные пробелы в вашем выражении, чтобы вы могли сделать его более читабельным:

my $pattern = qr{
    ^\s*
    constant\s*
    #etc
}x;

(Обратите внимание на модификатор x после конечной фигурной скобки.) Далее, как уже продемонстрировано в предыдущем примере, вы можете выбрать символ-разделитель для шаблона, чтобы вам не пришлось избегать косых черт в выражении :

my $pattern1 = qr/delimited by slashes/;
my $pattern2 = qr{delimited by curly braces};

И если вы хотите просто сгруппировать выражение, не вводя его в $1, $2 и т. Д., Вы можете использовать конструкцию (?:…):

if ('foo bar' =~ /(?:foo)\s*(bar)/) {
    say $1; # bar
}

Или, начиная с Perl 5.10, вы можете использовать именованные захваты:

if ('foo bar' =~ /(?<name>foo)\s*bar/) {
    say $+{name}; # foo
}

Все это должно сделать ваше регулярное выражение более читабельным. На главный вопрос вашего вопроса уже должны были ответить другие:)

2 голосов
/ 22 декабря 2009

Примите ваши данные:

constant fixup privite ConfigAlarms = <U1 0>         /*  comment here*/

И начните заменять переменные регулярными выражениями, оставляя константы в покое (также вам нужно экранировать Perl):

constant fixup privite (\w+) = <([a-zA-Z0-9]+) ([0-9]+)>         \/\*  (.*?) \*\/

Тогда вы можете сделать его устойчивым к пробелам:

constant\s+fixup\s+privite\s(\w+)\s+=\s+<([a-zA-Z0-9]+)\s+([0-9]+)>\s+\/\*(.*?)\*\/

Ваши переменные теперь в $ 1, $ 2 и $ 3.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...