Возвращение номеров строк регулярного выражения в нескольких строках - PullRequest
2 голосов
/ 27 января 2011

Я пытаюсь написать инструмент, который найдет пустые теги XML, которые охватывают несколько строк в большом текстовом файле.Например, не совпадают:

<tag>
ABC
</tag>

И совпадают:

<tag>
</tag>

У меня нет проблем с написанием регулярного выражения для сопоставления пробелов в нескольких строках, но мне нужно найти номера строкгде эти совпадения происходят (по крайней мере, по крайней мере).

Я бы разбил свой текстовый файл на массив, но тогда было бы довольно сложно сопоставить несколько элементов массива, так как может быть> 2 строки тегов /пробелы.

Есть идеи?Моя реализация должна быть в Perl.Спасибо!

Ответы [ 4 ]

4 голосов
/ 27 января 2011
if ($string =~ $regex) {
    print "Match starting line number: ", 1 + substr($string,0,$-[0]) =~ y/\n//, "\n";
}
3 голосов
/ 27 января 2011

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

0 голосов
/ 27 января 2011

Если вам нужно надежное решение, используйте реальный анализатор XML, а не простое сопоставление с образцом.

Если вы готовы использовать хрупкий подход, который не всегда может дать правильные ответы, затем смотрите ниже: -)

#!/usr/bin/perl
use warnings;
use strict;

my $xml =<<ENDXML;
<tag>
stuff
</tag>
<tag>


</tag>
<p>
paragraph
</p>
<tag> </tag>
<tag>
morestuff
</tag>
ENDXML

while ($xml =~ m#(<tag>\s*</tag>)#g) {
    my $tag = $1;

    # use substr() as an "lvalue" to find number of lines before </tag>
    my $prev_lines = substr($xml, 0, pos($xml)) =~ tr/\n// + 1;

    # adjust for newlines contained in the matched element itself
    my $tag_lines = $tag =~ tr/\n//;

    my $line = $prev_lines - $tag_lines;
    print "lines $line-$prev_lines\n$tag\n";
}
0 голосов
/ 27 января 2011

Если имеется только один <tag> на строку, вы можете использовать переменную specail $., которая содержит текущий номер строки.

#!/usr/bin/perl
use strict;
use warnings;
use 5.10.1;

my ($begin, $tag) = (0, 0, '');
while (my $line = <DATA>) {
  chomp $line;
  if ($line =~ m#<(tag).*?>#) {
    $tag = $1;
    $begin = $.;
    next;
  }
  if ($line =~ m#</($tag).*?>#) {
    if ($. - $begin < 2) {
      say "Empty tag '$tag' on lines $begin - $.";
    }
    $begin = 0;
    $tag = '';
  }
}

__DATA__
<tag>
ABC
</tag>

<tag>
</tag>

Выход:

Empty tag 'tag' on lines 5 - 6
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...