Регулярное выражение, динамическое число

#regex

#регулярное выражение

Вопрос:

Регулярное выражение, которое я предоставил, выделит строку 72719 .

Регулярное выражение:

 (?<=bdfg34f;d{4};)d{0,9}
  

Пример текста:

 vfhnsirf;5234;72159;2;668912;28032009;4;
bdfg34f;8467;72719;7;6637912;05072009;7;
b5g342sirf;234;72119;4;774582;20102009;3;
  

Как я могу переписать выражение, чтобы выбрать эту строку, даже если число 8467; изменено на 84677; или 846777; ? Возможно ли это?

Комментарии:

1. На данный момент я не использую никакой язык, я использую regexr.com ? 2tikn для целей тестирования. Я просто хотел спросить, возможно ли переписать приведенное выше выражение, чтобы показать точное число «72719», но с другим количеством чисел до или нет.

2. Причина, по которой я спрашиваю, заключается в том, что ответ зависит от того, поддерживает ли ваш язык: переменная длина lookbehind (большинство этого не делает). Если это произойдет (.NET), то решение Джеймса Кибурца будет работать. Если этого не произойдет, вам нужно будет использовать решение, подобное тому, которое я предложил.

3. @ridgerunner: Я предпочитаю называть это неограниченным поиском сзади, и AFAIK это поддерживается только .NET и JGsoft . Но некоторые варианты (в частности, Perl и PCRE) предлагают оператор сброса точки совпадения K в качестве альтернативы.

Ответ №1:

Во-первых, задавая вопрос с регулярным выражением, вы всегда должны указывать, какой язык вы используете. Предполагая, что используемый вами язык не поддерживает поиск переменной длины сзади (и большинство из них этого не делают), вот решение, которое будет работать. Ваше исходное выражение использует поиск фиксированной длины назад, чтобы соответствовать шаблону, предшествующему нужному вам значению. Но теперь этот предыдущий текст может иметь переменную длину, поэтому вы не можете использовать просмотр позади. Это не проблема. Просто сопоставьте предыдущий текст обычным образом и запишите ту часть, которую вы хотите сохранить в группе захвата. Вот протестированный фрагмент PHP-кода, который извлекает все значения из строки, записывая каждое значение в группу захвата $1 :

 $re = '/^bdfg34f;d{4,};(d{0,9})/m';
if (preg_match_all($re, $text, $matches)) {
    $values = $matches[1];
}
  

Изменения заключаются в:

  • Удалена группа lookbehind.
  • Добавлена привязка к началу строки и установлен многострочный режим.
  • Изменил d{4} «ровно четыре» на d{4,} «четыре или более».
  • Добавлена группа захвата для требуемого значения.

Ответ №2:

Вот как я обычно описываю «поля» в регулярном выражении:

[^;] ;[^;] ;([^;] );

Это означает «материал, который не является точкой с запятой, за которым следует точка с запятой», который описывает каждое поле. Сделайте это дважды. Затем выберите его в третий раз.

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

Кроме того, если это просто файл данных на диске и вы используете инструменты GNU, есть гораздо более простой способ сделать это:

cat file | cut -d";" -f 3

Комментарии:

1. Спасибо за вашу помощь. Интересное решение с использованием инструментов GNU, спасибо.

Ответ №3:

для сопоставления первого числа с минимум 4 цифрами

 (?<=bdfg34f;d{4,};)d{0,9}
  

и для сопоставления первого числа с длиной 1 или более

 (?<=bdfg34f;d ;)d{0,9}
  

или для сопоставления с первым числом, только если длина составляет от 4 до 6

 (?<=bdfg34f;d{4,6};)d{0,9}
  

Комментарии:

1. Спасибо за вашу помощь, я протестировал это на regexhero.net/tester и теперь я вижу, что это работает в .NET. Спасибо.

Ответ №4:

Это простая проблема синтаксического анализа текста, которая, вероятно, не требует использования регулярных выражений.

Вы могли бы брать входные данные построчно и разбивать на ‘;’, т.Е. (в php я понятия не имею, что вы делаете)

 foreach (explode("n", $string) as $line) {
    $bits = explode(";", $line);
    echo $bits[3]; // third column
}
  

Если это действительно в файле, и вы используете PHP, использование fgetcsv было бы намного лучше.

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