我试图为以下场景找到一个模式:
假设我有这个字符串:
someString[code]some code[/code]someString
现在有些代码可以是任何东西,我想要得到的是保留字(break、class等),所以对于真实场景,这是一个字符串:
someString
[code]
class someClass{}
[/code]
someString
// And again
someString
[code]
class someClass{}
[/code]
someString
因此,我试图理解的是,如何匹配所有[code][/code]标签之间的所有保留字。
例如:[code]someReservedWord some text anotherReservedWord[/code]
我只想匹配某个ReservedWord和另一个ReservedWord。
我想使用preg_match_all这样我就可以在每个[code][/code]中获取所有保留字,并使用preg_OFFSET_CAPTURE获取它们的位置,
我唯一弄不清楚的是模式,如果有人有这个想法,我会非常感谢,谢谢大家,祝你们度过美好的一天。
您可以使用这个:
$pattern = <<<'LOD'
~ (?(DEFINE) (?<words> class | string | function ) )
(?: '[code] | 'G(?<!^) )
(?: [^[]+? | '[(?!/code]) )*? 'K
'b 'g<words> 'b
~x
LOD;
preg_match_all($pattern, $subject, $matches, PREG_OFFSET_CAPTURE);
print_r($matches[0]);
图案细节:
首先,我们定义了一个带有所有保留字的命名组:
(?(DEFINE) (?<words> class | string | function ) )
(?(DEFINE)...)
语法允许在模式本身之外定义子模式。您可以稍后在模式中使用'g<words>
将命名组称为"words"。
(?: [^[]+? | '[(?!/code]) )*?
描述保留字之前的所有内容。此子模式可以匹配除结束标记[/code]
之外的所有内容,因为您可以在"不是[的所有内容"或"后面没有/code
的[的所有信息"之间进行选择。由于它可以匹配所有内容,因此当遇到保留字时,会使用惰性量词来停止匹配。
该模式的入口点是(?: '[code] | 'G(?<!^) )
。这将强制匹配从[code]
标记开始或与前一个匹配相邻。
('G
是一个锚,意思是:"在字符串的开头或与前一个匹配相邻"。如果使用负查找(?<!^)
,则禁止字符串的开头。)
CCD_ 11是一种从匹配结果中重置之前所有匹配内容的技巧。
$str = "someString[code]some code[/code]someString";
$ret = preg_replace('#'[code'](.+)'['/code']#iUs', '<FOUND>$1</FOUND>', $str);
var_dump($ret);
(http://www.phpliveregex.com/p/2tD,参见preg_match_all示例)
你可能会在谷歌上搜索BB代码PHP正则表达式。