Как я могу сделать это регулярное выражение более компактным? - PullRequest
1 голос
/ 16 ноября 2008

Допустим, у меня есть такая строка текста

Small   0.0..20.0   0.00    1.49    25.71   41.05   12.31   0.00    80.56

Я хочу захватить последние шесть чисел и игнорировать Маленькое и первые две группы чисел.

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

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

^(Small).*?[0-9.]+.*?[0-9.]+.*?([0-9.]+).*?([0-9.]+).*?([0-9.]+).*?([0-9.]+).*?([0-9.]+).*?([0-9.]+)

Есть ли способ сжать это?

Например, возможно ли объединить проверку для последних 6 чисел в один оператор, который по-прежнему сохраняет результаты как 6 отдельных совпадений групп?

Ответы [ 3 ]

5 голосов
/ 16 ноября 2008

Если вы хотите сохранить каждый матч в отдельной обратной ссылке, у вас нет другого выбора, кроме как «прописать» - если вы используете повторение, вы можете поймать все шесть групп «как одну» или только последнюю, в зависимости на том, где вы ставите захват скобки. Так что нет, невозможно сжать регулярное выражение и сохранить все шесть отдельных матчей.

Несколько более эффективным (хотя и не красивым) регулярным выражением будет:

^Small\s+[0-9.]+\s+[0-9.]+\s+([0-9.]+)\s+([0-9.]+)\s+([0-9.]+)\s+([0-9.]+)\s+([0-9.]+)\s+([0-9.]+)

, поскольку он явно соответствует пробелам. Ваше регулярное выражение приведет к большому отступлению. Мое регулярное выражение совпадает с 28 шагами, твое - с 106.

Так же, как в сторону: в Python вы можете просто сделать

>>> pieces = "Small   0.0..20.0   0.00    1.49    25.71   41.05   12.31   0.00    80.56".split()[-6:]
>>> print pieces
['1.49', '25.71', '41.05', '12.31', '0.00', '80.56']
3 голосов
/ 16 ноября 2008

Вот самое короткое, что я мог получить:

^Small\s+(?:[\d.]+\s+){2}([\d.]+)\s+([\d.]+)\s+([\d.]+)\s+([\d.]+)\s+([\d.]+)\s+([\d.]+)\s*$

Он должен быть длинным, потому что каждый захват должен быть указан явно. Не нужно захватывать «Малый», хотя. Но лучше быть точным (\ s вместо.), Когда это возможно, и привязывать оба конца.

1 голос
/ 16 ноября 2008

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

$d = "[0-9.]+"; 
$s = ".*?"; 

$re = "^(Small)$s$d$s$d$s($d)$s($d)$s($d)$s($d)$s($d)$s($d)";

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

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

$re = "^(Small)_#D_#D_(#D)_(#D)_(#D)_(#D)_(#D)_(#D)"; 
$re = str_replace('#D','[0-9.]+',$re); 
$re = str_replace('_', '.*?' , $re ); 

(Таким образом, это также делает тривиальным изменение определения того, что является пробелом или что такое цифра)

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