Regex - многострочная задача - PullRequest
3 голосов
/ 28 мая 2009

Я думаю, что я сгорел, и поэтому не вижу очевидной ошибки. В любом случае, я хочу следующее регулярное выражение:

# БИЗ [. \ S] * # ENDBIZ

чтобы получить тег #BIZ, тег #ENDBIZ и весь текст между тегами. Например, если дан некоторый текст, я хочу, чтобы выражение совпадало:

#BIZ
some text some test
more text
maybe some code
#ENDBIZ

На данный момент регулярное выражение ничего не соответствует. Что я сделал не так?

ДОПОЛНИТЕЛЬНЫЕ ДАННЫЕ

Я делаю следующее в PHP

preg_replace ('/ # BIZ [. \ S] * # ENDBIZ /', 'мой новый текст', $ strMultiplelines);

Ответы [ 8 ]

13 голосов
/ 28 мая 2009

Точка теряет свое особое значение внутри класса символов - другими словами, [.\s] означает «период совпадения или пробел». Я считаю, что вы хотите, чтобы [\s\S], "сопоставить пробел или не пробел".

preg_replace('/#BIZ[\s\S]*#ENDBIZ/', 'my new text', $strMultiplelines);

Редактировать: Немного о точечных и символьных классах:

По умолчанию точка не соответствует символу новой строки. В большинстве (всех?) Реализаций регулярных выражений есть способ указать, что он также соответствует символу новой строки, но отличается от реализации. Единственный способ сопоставить (действительно) любой символ совместимым способом - это связать сокращенный класс с его отрицанием - [\s\S], [\w\W] или [\d\D]. По моему личному опыту, первое кажется наиболее распространенным, вероятно, потому, что оно используется, когда вам нужно сопоставить символы новой строки, и включение \s дает понять, что вы делаете это.

Кроме того, точка - не единственный специальный символ, который теряет свое значение в классах символов. Фактически, единственными символами, которые являются особыми в классах символов, являются ^, -, \ и ]. Ознакомьтесь с разделом «Метасимволы внутри классов символов» на странице классов символов на Regular-Expressions.info .

2 голосов
/ 28 мая 2009

Это должно работать

# БИЗ [\ s \ S] * # ENDBIZ

Вы можете попробовать это онлайн Средство тестирования регулярных выражений

2 голосов
/ 28 мая 2009
// Replaces all of your code with "my new text", but I do not think
// this is actually what you want based on your description.
preg_replace('/#BIZ(.+?)#ENDBIZ/s', 'my new text', $contents);

// Actually "gets" the text, which is what I think you might be looking for.
preg_match('/(#BIZ)(.+?)(#ENDBIZ)/s', $contents, $matches);
list($dummy, $startTag, $data, $endTag) = $matches;
1 голос
/ 28 мая 2009

Ошибка в группе символов [.\s], которая будет соответствовать точке (не любому символу) или пробелу. Вы, вероятно, также пытались получить .* с . соответствующими символами новой строки. Этого можно достичь, включив однострочный параметр ((?s:) делает это в регулярном выражении .NET).

(?s:#BIZ.*?#ENDBIZ)
1 голос
/ 28 мая 2009

В зависимости от среды, в которой вы используете регулярное выражение, может потребоваться особая осторожность для правильного анализа многострочного текста, например re.DOTALL в Python. Так что же это за среда?

0 голосов
/ 28 мая 2009

вы можете использовать

preg_replace('/#BIZ.*?#ENDBIZ/s', 'my new text', $strMultiplelines);

модификатор 's' говорит: "сопоставьте точку с чем угодно, даже символом новой строки" '?' говорит не жадничать, например, для случая:

foo

#BIZ
some text some test
more text
maybe some code
#ENDBIZ

bar

#BIZ
some text some test
more text
maybe some code
#ENDBIZ

hello world

Жадность не избавит от "бара" в середине.

0 голосов
/ 28 мая 2009

Если я что-то упустил, вы справляетесь с этим так же, как и в Perl , с модификатором /m или /s в конце? Как ни странно, другие ответы , которые довольно правильно указали на это, получили , проголосовавших ?!

0 голосов
/ 28 мая 2009

Похоже, вы выполняете регулярное выражение javascript, вам нужно включить многострочный, указав флаг m в конце выражения:

var re = /^deal$/mg 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...