PHP/Regex:bbcode[s]或[strike]的简单Regex无法工作
对于一个愚蠢的bbcode解析器,我想在其中添加两个定义,我最初的定义是preg_替换:PHP/Regex:bbcode[s]或[strike]的简单Regex无法工作,php,regex,bbcode,Php,Regex,Bbcode,对于一个愚蠢的bbcode解析器,我想在其中添加两个定义,我最初的定义是preg_替换: '#\[s\](.*?)\[/s\]#si', '<strike>\\1</strike>' 不幸的是,这失败了,而不是你所期望的,[s]和[strike](正确使用)make:s和strike(我的标记正确地显示了它真实的外观结果,它显示了s或strike,不管里面是什么) 为什么它用标记名替换内部文本?我在s | strike的周围添加括号是否有问题?我可能完全错了。问题是您添
'#\[s\](.*?)\[/s\]#si', '<strike>\\1</strike>'
不幸的是,这失败了,而不是你所期望的,[s]
和[strike]
(正确使用)make:s
和strike
(我的标记正确地显示了它真实的外观结果,它显示了s或strike,不管里面是什么)
为什么它用标记名替换内部文本?我在s | strike的周围添加括号是否有问题?我可能完全错了。问题是您添加了两个新的正则表达式组,
(s | strike)
在开始标记中,而(s | strike)
在结束标记中。因此,在生成的代码中,您将得到s
或strike
。您只需使用正确的组号2
即可解决此问题
另一种方法是通过在开头添加一个?:
,使新组成为非引用组,但我想第一种解决方案更容易理解:
\[(?:s|strike)\](.*)\[/(?:s|strike)\]si
BBcode不是常规代码。使用@Gordon:你找错人了。现代正则表达式几乎与常规语言和兼容性类无关。自从Ken Thompson第一次在他的回溯NFA代码中加入()\1
(grep)以来,正则表达式就不是正则表达式:()\1
描述的语言在st00pid教科书中的正则性定义中不是正则的,没有人使用,也不适用于现代正则表达式。@Gordon:那篇文章错了!我可以很容易地做出一个他无法打破的模式。他不是在谈论现代正则表达式,只是在谈论教科书上的正则表达式,一些没有人使用的东西。即使是egrep
也可以匹配()\1
,这是不规则的。请参见和-&c&c&c@戈登:你不是说不可行;你的意思是不实用,或者也许不是权宜之计。我当然不建议重新发明完美的车轮。我只是厌倦了人们无意识地重复这句老生常谈,“你不能用正则表达式做X”,而他们真正的意思是“我们不知道如何做”、“不要这样做”或“有更简单的方法来实现你的目标”。这是轻蔑、虚伪,甚至是不诚实的。但是Querent一家应该明白,把所有的东西都放在一个正则表达式中并没有道德优势;戈登:恰恰相反,我强烈反对你的观点。高级术语REGULAR的误用与实际模式匹配无关。它有一个高度不规则和完全违反直觉的意思,欺骗任何人,除了一个象牙塔的书呆子。我听腻了你和其他人假装正则表达式是正则表达式。它们不是,甚至要求它们不是:请注意,即使是POSIX BRE也必须支持backref,从而为您所有的常规教皇造假\((?:[^()]*+|(?0))*\)
是一个漂亮的正则表达式。啊,谢谢,这有助于我的理解。我以为只有(.*)
才能抓到一个群,我完全忘了(任何东西)
也可以。编辑:但是第一个(s | strike)
也组成一个组吗?为什么只是第二个?第一个是\0吗?让我困惑的是,我可能会在睡觉后得到它:PAll(..)
捕获组(除非它以?:
开头)。但是组是以1
开始编号的,因为“组”0
通常表示整个匹配的字符串(在本例中是[s]一些文本[/s]
)。哦!!。。现在我完全明白了。谢谢:)命名组也很吸引人(对不起☺) 在(?…)
中使用。它们也有编号,但首选的访问方式是从模式内部访问\k
,从外部访问$+{GROUP\u NAME}
。在一些情况下,您可以引用编号或命名的组,而不使用backref符号。大多数情况下是在(条件)YES\u PART | NO\u PART)
条件模式的条件测试。您可以编写((2)…|…)
或(…|…)
。还有一些递归测试,您不使用反斜杠来谈论组。命名组优于编号组。
'#\[(s|strike)\](.*?)\[/(s|strike)\]#si', '<strike>\\1</strike>'