【问题标题】:Regular expression that finds [abc] but not [;;abc]查找 [abc] 但不查找 [;;abc] 的正则表达式
【发布时间】:2021-03-15 16:12:05
【问题描述】:

这么晚了,我还真搞不明白。

我的文字是这样的:

 This is a [;;Text] and I want to match [center]everything without ;;[/center]

我用它来转换成 HTML:

 return preg_replace('/\[(.+)\]/U', '<$1>', $text);

我认为模式 /\[[^;{2}](.+)\]/U 应该可以解决问题,但它不起作用。

【问题讨论】:

  • 您不应该在 [] 中使用 {}。您可以使用此模式 [[;]{2}(.+)]
  • 嗯,它不起作用。它仍然与“;;”匹配的东西
  • 哦,请试试这个[(?!;)(.*)]
  • 为什么需要匹配这个语法?因为这里最好的答案是“尽可能停止使用这种语法”,而不是使用正则表达式,可能开始使用真正的模板引擎?
  • 你能告诉我什么是模板引擎,我可以使用哪一个?它是我加载到我的项目中然后用来替换模板标记的外部 php 库吗?

标签: php regex


【解决方案1】:

例如,您可以匹配[ 和可选的/,后跟单词字符,直到结束]

请注意,在这种情况下,您不需要 /U 标志来使量词变得惰性。

\[/?\w+]

$text = ' This is a [;;Text] and I want to match [center]everything without ;;[/center]';
$result = preg_replace('/\[(\/?\w+)]/', "<$1>", $text);
echo $result;

输出

This is a [;;Text] and I want to match <center>everything without ;;</center>

Regex demo


对于更具体的匹配,您可以在 [ 之后排除匹配的 ;;,并使用否定字符类匹配除 [] 之外的所有字符。

\[(?!;;)([^][]*)]

Regex demo

【讨论】:

  • 非常好的负前瞻用法。试图通过消极的后视来解决这个问题,但无法让它发挥作用。谢谢。这个很好,因为它还捕获了 [center;] 之类的条目
  • [(?!;;)([^][]*)] 这个作品非常完美!谢谢!
  • 我看到你重新打开了这个问题,我想知道stackoverflow.com/questions/66573222 是否也不是重复的?
  • @RyszardCzech 我重新打开它是因为恕我直言,我认为 SO 是一个帮助程序员处理他们尝试过但失败的代码的地方。许多正则表达式问题可能有与所用技术相关的重复答案,但在这种情况下,我将否定字符类更改为前瞻,并将量词更改为否定字符类以更新我认为的模式使用更好的模式。如果你真的认为那不是骗子,你可以重新打开stackoverflow.com/questions/66573222/…
【解决方案2】:

我发现了以下模式: \[(?&lt;!\;\;)([\w\/]+?)\]

演示链接: https://regex101.com/r/Htd32j/1

请注意,它仅在特定情况下匹配,如果您想要任何带有空格或其他特殊字符的标签,它将不起作用并且可能需要进行一些修改。

【讨论】:

  • 此断言将始终为真\[(?&lt;!\;\;),因为您首先匹配[,然后断言直接向右不是;;
  • 我只匹配括号中的标签,这就是出现在 regex101 中的内容,我假设我们只是在谈论标签。
  • 是的,但您可以省略(?&lt;!\;\;),因为它没有效果。您也可以省略+? 之后的问号以使其不贪心。 \w 不能匹配 ] 所以你可以省略它。
  • 我想尽可能具体,但你说得对,这能解决你的问题吗?
  • 对我来说没有问题 :-) 我只是将它添加为一个小提示,即模式可以简化。
【解决方案3】:

如果您想通过跳过 ; 的出现来仅提取 [] 内的文本,您可以尝试以下操作。我刚刚修改了@Mehdi 正则表达式。

(?&lt;=\[;;)?\w+(?=\])

检查https://regex101.com/中的表达式是否为php。

检查下面的链接。

https://regex101.com/r/bFyW8S/1

【讨论】:

    【解决方案4】:

    我想出的匹配这个模式的正则表达式非常简单:

    [[][A-Za-z0-9]*[]]
    

    将其分解为更小的部分以便理解:

    [[] begins with "["
    
    [A-Za-z0-9]* contains one or more alphabet or numeric character
              
    []] ends with "]"
    

    这将匹配 [center] 但不匹配 [/center] 或 [;;Text],因为它们具有特殊字符,并且正则表达式只查找字母和数字。


    编辑:如果你想匹配除“;”之外的所有字符那么你可以使用这个:

    [[][^;]*[]]
    

    遵循非常相似的逻辑:

    [[] begins with "["
    
    [^;]* one or more character that is not ";"
    
    []] ends with "]"
    

    将匹配 [center][/center] 但不匹配 [;;Text]

    【讨论】:

    • 你测试这个构造[Aa-Zz] 吗?这个[A-z] 也与[A-Za-z] 不同,使用像([Aa-Zz]|[0-9]) 这样的结构也不是很有效的交替。你可以写成[A-Za-z0-9]*
    • 我在 regex101 上为 php 做的测试似乎不喜欢 [Aa-Zz],但对 [A-z] 没问题。我不怀疑你是对的。
    • [A-z] 是一个有效范围,但看到这个答案什么字符将匹配stackoverflow.com/questions/29771901/…
    • 感谢您澄清这一点,并根据您提供的建议对答案进行更改。
    • 对于第一个模式,您可以匹配可选的正斜杠以匹配两者,请参阅regex101.com/r/qSXluT/1。对于第二个模式,您在正确的轨道上,但是看看如果中间的字符串不包含 ; regex101.com/r/PaZWml/1 会发生什么情况,它会过度匹配它。如果您不想在方括号内也允许使用分号,您还可以在这种情况下排除方括号,请参阅regex101.com/r/MQsLBy/1
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-09
    • 1970-01-01
    • 2018-12-13
    • 1970-01-01
    相关资源
    最近更新 更多