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

Как мне создать регулярное выражение, которое будет извлекать текст с разделителями из строки? Например, заданная строка типа

text ###token1### text text ###token2### text text 

Я хочу регулярное выражение, которое вытащит ###token1###. Да, я тоже хочу разделитель. Добавив другую группу, я могу получить оба:

(###(.+?)###)

Ответы [ 7 ]

4 голосов
/ 17 сентября 2008
/###(.+?)###/

если вы хотите ###, тогда вам нужно

/(###.+?###)/

? означает не жадный, если бы у вас не было ? , то он бы хватил слишком много

например. '###token1### text text ###token2###' всех схватят.

Мой первоначальный ответ был * вместо +. * означает 0 или больше. + означает 1 или более. * было неправильно, потому что это позволило бы ###### как действительную вещь найти.

Для игры с регулярными выражениями. Я настоятельно рекомендую http://www.weitz.de/regex-coach/ для Windows. Вы можете ввести желаемую строку и ваше регулярное выражение и посмотреть, что он на самом деле делает.

Ваш выбранный текст будет сохранен в \ 1 или $ 1 в зависимости от того, где вы используете регулярное выражение.

1 голос
/ 17 сентября 2008

В Perl вы действительно хотите что-то вроде этого:

$text = 'text ###token1### text text ###token2### text text';

while($text =~ m/###(.+?)###/g) {
  print $1, "\n";
}

Что даст вам каждый жетон по очереди в цикле while. (. *?) Гарантирует, что вы получите кратчайший бит между разделителями, не давая ему думать, что токен является 'token1 ### text text ### token2'.

Или, если вы просто хотите сохранить их, не зацикливайтесь сразу:

@tokens = $text =~ m/###(.+?)###/g;
0 голосов
/ 17 сентября 2008

Хорошо, когда вы используете такие разделители, как этот, вы просто берете первый, а затем все, что не соответствует конечному разделителю, за которым следует конечный разделитель. Особое предостережение должно заключаться в том, что в случаях, как в приведенном выше примере, [^ #] не будет работать как проверка, чтобы убедиться, что конечный разделитель отсутствует, так как одиночный # приведет к сбою регулярного выражения (т.е.. "### foo # bar # ##). В приведенном выше регулярном выражении для синтаксического анализа было бы следующее, предполагая, что пустые токены разрешены (если нет, измените * на +):

### ([^ #] | # [^ #] | ## [^ #]) * ###

0 голосов
/ 17 сентября 2008

Используйте () и \ x. Наивный пример, предполагающий, что текст в токенах всегда отделяется #:

text (#+.+#+) text text (#+.+#+) text text

Материал в () может быть получен с помощью \ 1 и \ 2 (\ 1 для первого набора, \ 2 для второго в выражении замены (если вы выполняете поиск / замену в редакторе Например, выражение замены может быть:

token1: \1, token2: \2

Для приведенного выше примера это должно привести к:

token1: ###token1###, token2: ###token2###

Если вы используете библиотеку регулярных выражений в программе, вы, вероятно, вызываете функцию для получения содержимого первого и второго токенов, которые вы указали с помощью () вокруг них.

0 голосов
/ 17 сентября 2008

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

http://www.regular -expressions.info /

0 голосов
/ 17 сентября 2008

Проверить Regex Buddy Джефф рекомендовал его несколько раз http://www.codinghorror.com/blog/archives/000027.html

0 голосов
/ 17 сентября 2008

Предполагая, что вы также хотите сопоставить ### token2 ### ...

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