Perl Regexp :: Общий пакет не совпадает с определенными действительными числами при использовании со словом границ - PullRequest
3 голосов
/ 13 мая 2019

Приведенный ниже код выводит «34» вместо ожидаемого «.34»

use strict;
use warnings;

use Regexp::Common;

my $regex = qr/\b($RE{num}{real})\s*/;
my $str = "This is .34 meters of cable";

if ($str =~ /$regex/) {
    print $1;
}

Нужно ли исправлять мое регулярное выражение?(Граница слова является нужной, так как она не включена, потому что она будет соответствовать строке типа xx34, чего я не хочу)

Или это ошибка в Regexp :: Common?Я всегда думал, что самый длинный матч должен выиграть.

Ответы [ 2 ]

2 голосов
/ 13 мая 2019

Граница слова - это контекстно-зависимая конструкция регулярного выражения.Когда за ним следует слово char (буква, цифра или _), этому местоположению должен предшествовать либо начало строки, либо не состоящее из слова char.В этом конкретном случае за границей слова следует символ, не содержащий слова char, и поэтому требуется, чтобы слово char отображалось непосредственно перед этим символом.

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

my $regex = qr/(?<!\w)($RE{num}{real})/;
               ^^^^^^^

Отрицательный внешний вид (?<!\w) всегда обозначает одну вещь: провалить совпадение, если слева от текущего местоположения нет символа слова.

Или используйте границу пробелаесли вы хотите, чтобы ваши совпадения появлялись только после пробела или начала строки:

my $regex = qr/(?<!\S)($RE{num}{real})/;
               ^^^^^^^
0 голосов
/ 13 мая 2019

Попробуйте этот патерн: (?:^| )(\d*\.?\d+)

Пояснение:

(?:...) - группа без захвата

^| - соответствует либо ^ - начало строки, либо - пробел

\d* - соответствует нулю или более цифрам

\.? - буквально совпадать с точкой - ноль или единица

\d+ - соответствует одной или нескольким цифрам

Совпадающий номер будет сохранен в первой группе захвата.

Демо

...