Инверсия модификатора Perl regex X - PullRequest
2 голосов
/ 14 мая 2011

Я хотел бы использовать регулярное выражение Perl для соответствия строк следующим образом:

spaM
s p a m
sp Am
S   p a   m

Глядя на модификатор Perl x, я смогу сделать это:

<?php
echo preg_match('#spam#ix', 's p a   m');
?>

Но это выводит 0 (false).Модификатор x фактически игнорирует пробел в регулярном выражении, а не анализируемую строку.Как бы я сделал это наоборот?То есть игнорировать пробел в анализируемой строке, а не в моем регулярном выражении?Я знаю, что есть многошаговые способы сделать это, например, сначала убрать все пустое пространство из строки, но я хотел знать, было ли мощное одношаговое решение для регулярных выражений.

Ответы [ 3 ]

7 голосов
/ 14 мая 2011

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

Perl для этого будет выглядеть примерно так.

my $string = "S   p A m";
(my $string_no_ws = $string) =~ s/\s//g;
if ($string_no_ws =~ /spam/i) {
  #do something
}

на самом деле вы можете сделать тест без регулярных выражений, если хотите, используя index:

my $string = "S   p A m";
(my $lc_string_no_ws = lc $string) =~ s/\s//g;
if (index($lc_string_no_ws, 'spam') >= 0) {
  #do something
}
6 голосов
/ 14 мая 2011

Модификатор #x работает наоборот. Это позволяет использовать посторонние пробелы в регулярных выражениях, которые игнорируются при поиске:

preg_match('# s p a m #ix')

Будет совпадать только со спамом.

То, что вам нужно сделать, чтобы найти произвольное пространство с вашим регулярным выражением, это ввести \s* между любыми буквами:

preg_match('# S \s* P \s* A \s* M #ix', 's p a   m');

Вы можете немного автоматизировать / упростить это, преобразовав слова в соответствующее регулярное выражение с перемешанным \s*, используя:

$regex = join('\s*', str_split("spam", 1));
preg_match("#$regex#ix", "s p a m");
3 голосов
/ 14 мая 2011

модификатор /x для регулярного выражения в perl относится к конструкции регулярного выражения, а не к тому, что сопоставляется.Чтобы соответствовать имеющимся у вас значениям, вы хотите

/s\s*p\s*a\s*m\s*/i

, если порядок имеет значение для слова спам, а если нет, то что-то вроде

/[spam \t\n\r]+/ 

будет достаточно

...