我遇到了正则表达式的问题:
$var = preg_replace("/\[doxer_quote\]([^]]+)\[\/doxer_quote\]/", '<blockquote>$1</blockquote>', $var);
我试图让它显示blockquote
标记内的内容,但我无法弄明白。它也需要经过多行。有人可以帮助我。
答案 0 :(得分:3)
你的正则表达式适用于[doxer_quote]
内不包含“标签”的字符串,例如:
[doxer_quote]my
multiline
text[/doxer_quote]
但它使用嵌套标签失败,即使是单行内容,例如:
[doxer_quote]my [strong]formatted[/strong] text[/doxer_quote]
原因是您通过重复的字符类]
将所有内容与[^]]+
字符进行匹配,因此在满足第一个嵌套标记时它会中断。
解决方案:将[^]]+
替换为.+
,将和包含s
- 修改为您的正则表达式,即:
$var = preg_replace("/\[doxer_quote\](.+)\[\/doxer_quote\]/s", '<blockquote>$1</blockquote>', $var);
s
- 修饰符(称为PCRE_DOTALL)使点匹配任何字符,包括换行符。
如果允许您的标记语言包含嵌套的[doxer_quote]
元素,那么它不是regular。正则表达式仅用于处理常规语言。
没有优雅的方式来匹配正则表达式的嵌套元素。想一想以下情况:
[doxer_quote]
[doxer_quote]
Lorem ipsum dolor sit amet
[/doxer_quote]
[/doxer_quote]
consetetur sadipscing elitr
[doxer_quote]
sed diam nonumy
[/doxer_quote]
您无法使用单个正则表达式调用来处理它 但它可以循环完成如下:
while(($var2 = preg_replace("/\[doxer_quote\]((?:(?!\[doxer_quote\]).)+?)\[\/doxer_quote\]/s", '<blockquote>$1</blockquote>', $var)) !== $var)
$var = $var2;
分步说明:
.
匹配任何字符
(?!\[doxer_quote\]).
匹配任何字符,这不是序列“[doxer_quote]”的开头。 (?!)
被称为negative lookahead。
(?:(?!\[doxer_quote\]).)
以上分组为non-capturing subpattern。
(?:(?!\[doxer_quote\]).)+
与子模式repeated匹配一次或多次。
(?:(?!\[doxer_quote\]).)+?
- ?
重复量词后+
生成量词lazy(也称为非贪婪)。
((?:(?!\[doxer_quote\]).)+?)
- 括号定义capturing subpattern。它在替换表达式中由$1
引用。
在循环中,每个步骤都会替换最里面的标记。如果字符串在迭代后没有改变,则循环中断。
如果您确定您的标记始终格式正确(例如,每个开始标记都已关闭)且标记语言的标记不包含属性等,请考虑replacing开始标记并结束直接标记,不匹配内容:
$var = str_replace(
array('[doxer_quote]', '[/doxer_quote]'),
array('<blockquote>', '</blockquote>'),
$var
);
您可以通过这种方式一步处理多个代码(不仅[doxer_quote]
)。
考虑解析您的标记语言。
答案 1 :(得分:-1)
见https://stackoverflow.com/a/2101427/2277620。使用multiline-modifier,但是如果你留下“+”贪婪,你将获得从第一个块开始到最后一个块结束的文本。