【问题标题】:Regex for matching text between unescaped underscore用于匹配未转义下划线之间的文本的正则表达式
【发布时间】:2017-01-05 07:55:24
【问题描述】:

我正在尝试用标签替换下划线之间的文本。 这是我目前使用的模式(链接到在线测试器:TESTER):

[^\\]?_(([^_]*)[^\\])_

这是我想要得到的结果:

_test1_ _test2__test3_ \_test4\_ => <b>test1</b> <b>test2</b><b>test3</b> \_test4\_

谁能告诉我我的模式有什么问题?

【问题讨论】:

  • 尝试(?&lt;!\\)((?:\\{2})*)_([^_\\]*(?:\\.[^_\\]*)*)_(替换为$1&lt;b&gt;$2&lt;/b&gt;)。在 PHP 中,\ 必须在模式中定义为\\\\
  • 你能解释一下模式的第一部分吗? (?
  • (?&lt;!\\)((?:\\{2})*)_ 部分匹配未转义的 _:任意数量的双 \ 符号前面没有 \。它是否按预期工作?
  • 是的,它工作得非常好,谢谢:)

标签: php regex string replace


【解决方案1】:

你可以使用

(?<!\\)((?:\\{2})*)_([^_\\]*(?:\\.[^_\\]*)*)_

PHP 声明:

$pattern = '~(?<!\\\\)((?:\\\\{2})*)_([^_\\\\]*(?:\\\\.[^_\\\\]*)*)_~';

regex demo

详情

  • (?&lt;!\\)((?:\\{2})*)_ - 匹配未转义的 _:任意数量的双 \ 符号(参见 (?:\\{2})*,0+ 两个连续 \ 符号的序列),前面没有 \ ((?&lt;!\\) 负数lookbehind 执行此检查)
  • ([^_\\]*(?:\\.[^_\\]*)*)_ - 匹配除_ 以外的任意数量的符号或任意数量的转义符号,因此仅匹配第一个未转义的_
    • [^_\\]* - 匹配除 \_ 之外的 0+ 个字符
    • (?:\\.[^_\\]*)* - 0+ 个序列:
      • \\. - 任何转义字符(如果您使用 s DOTALL 修饰符,甚至是换行符)
      • [^_\\]* - 除了 \_ 之外的 0+ 个字符

要在 JavaScript 和其他不支持后视的正则表达式引擎中使用相同的方法,请使用 (^|[^\\]) 组而不是 (?&lt;!\\)

(^|[^\\])((?:\\{2})*)_([^_\\]*(?:\\.[^_\\]*)*)_

并替换为$1$2&lt;b&gt;$3&lt;/b&gt;。见this regex demo

【讨论】:

  • 有没有办法做到这一点没有负面的看法?因为我也想对 JavaScript 函数使用相同的处理,而 JS 似乎没有提供...
  • 是的,有几种方法可以在 JS 中模拟负面的回溯。我在答案中添加了与 JS 兼容的解决方案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-03-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多