正则表达式 - 多线问题

时间:2009-05-27 23:44:45

标签: regex

我想我已经筋疲力尽,这就是为什么我看不出明显的错误。无论如何,我想要以下正则表达式:

#BIZ [\ S] *#ENDBIZ

抓住#BIZ标签,#ENDBIZ标签以及标签之间的所有文字。例如,如果给出了一些文本,我希望表达式匹配:

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

目前,正则表达式并不匹配。我做错了什么?

其他详细信息

我正在PHP中执行以下操作

preg_replace('/#BIZ [。\ s] *#ENDBIZ /','我的新文字',$ strMultiplelines);

8 个答案:

答案 0 :(得分:13)

点在字符类中失去其特殊含义 - 换句话说,[.\s]表示“匹配句点或空格”。我相信你想要的是[\s\S],“匹配空白或非空白”。

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

编辑:关于点和字符类的一点:

默认情况下,点与换行符不匹配。大多数(所有?)正则表达式实现都有一种方法来指定它匹配换行符,但它因实现而不同。以兼容方式匹配(真正)任何字符的唯一方法是将速记类与其否定 - [\s\S][\w\W][\d\D]配对。根据我的个人经验,第一个似乎是最常见的,可能是因为当你需要匹配换行符时使用它,并且包括\s表明你正在这样做。

此外,点不是唯一在字符类中失去意义的特殊字符。实际上,字符类中唯一特殊的字符是^-\]。查看the character classes page on Regular-Expressions.info的“字符类中的元字符”部分。

答案 1 :(得分:2)

// 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;

答案 2 :(得分:2)

这应该有效

#BIZ [\ S \ S] *#ENDBIZ

您可以在线试用Regular Expression Testing Tool

答案 3 :(得分:1)

根据您正在使用正则表达式的环境,可能需要特别注意正确解析多行文本,例如Python中的re.DOTALL。那是什么环境?

答案 4 :(得分:1)

错误是与点(不是任何字符)或空格匹配的字符组[.\s]。您可能也试图通过.*匹配换行符来获取.。您可以通过启用单行选项来实现此目的((?s:)在.NET正则表达式中执行此操作。)

(?s:#BIZ.*?#ENDBIZ)

答案 5 :(得分:0)

除非我遗漏了某些内容,否则您的处理方式与Perl相同,最后使用/m or /s修饰符?奇怪的是other answers相当正确地指出了这个down voted?!

答案 6 :(得分:0)

你可以使用

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

非贪婪不会摆脱中间的“酒吧”。

答案 7 :(得分:-1)

看起来你正在使用javascript正则表达式,你需要通过在表达式的末尾指定m标志来启用多行:

var re = /^deal$/mg