【问题标题】:Regular expression works in Javascript but not PHP preg_match正则表达式在 Javascript 中有效,但在 PHP preg_match 中无效
【发布时间】:2013-08-29 12:26:06
【问题描述】:

正则表达式:

/([^]+):([^\\r\\n]+)/

字符串:

f1:aaa\r\nf2:bbb\r\nf3:ccc\r\nf4:ddd

根据 regexpal.com,这将提供我想要的集合:f1 & aaa, f2 & bbb, f3 & ccc 等。 但是使用http://www.functions-online.com/preg_match.html 我只看到[0] => "f1" and [1] => "f1"

谁能告诉我应该怎么做?

【问题讨论】:

  • 你有一个空字符集:[^].
  • @JasonMcCreary,这导致它无法使用 preg_match?
  • 这应该会导致它无法在任何地方工作……令人惊讶的是它在 JavaScript 中按预期工作。

标签: php regex


【解决方案1】:

一些 javascript 实现允许 [] 和 [^] 分别作为 "no character" 和 "any character"。但请记住,这是 javascript 正则表达式特有的。 (如果您对此主题感兴趣,可以查看this post。)

换句话说,[^] 是 [\s\S] 的快捷方式,因为 javascript 没有点可以匹配换行符的 dotall 或 singleline 模式。

因此,要在 PHP 中获得相同的结果,您必须将 [^] 替换为 .(默认匹配除换行符之外的任何字符),在结束分隔符之后使用单行修饰符 s 或在 @ 之前使用 (?s) 987654330@ 也允许换行。示例:/.+/s 或 /(?s).+/

但对于您的特定情况,这种模式似乎更合适:

preg_match_all('~((?>[^rn\\\:]++|(?<!\\\)[rn])+):([^\\\]++)~', $subject, $matches, PREG_SET_ORDER);

foreach ($matches as $match) {
    echo $match[1].' '.$match[2].'<br/>';
}

模式说明:

~                    # pattern delimiter
(                    # open the first capturing group
    (?>              # open an atomic group
        [^rn\\\:]++  # all characters that are not "r", "n", "\" or ":"
      |              # OR
        (?<!\\\)[rn] # "r" or "n" not preceded by "\"
    )+               # close the atomic group and repeat one or more times
)                    # close the first capturing group
:
(                    # open the second capturing group
    [^\\\]++         # all characters except "\" one or more times
)                    # close the second capturing group
~

注意事项:

当您想在用单引号括起来的字符串中表示\(反斜杠)时,必须使用双转义符:\\\

这种模式的原理是使用否定字符类和否定断言,换句话说,它查找所需的子字符串不能是什么。

上述模式使用原子组(?&gt;...) 和所有格量词++ 代替非捕获组(?:...) 和简单量词+。除了正则表达式引擎在原子组和所有格量词失败时无法返回测试其他方式外,其他方式相同,因为它不记录回溯位置。借助此类功能,您可以在性能上取胜。

【讨论】:

  • + 解释[^],我正要问一个单独的问题。希望我能 ++。
【解决方案2】:

尝试:

/([a-z0-9]+):([a-z0-9]+)(?:\r\n)?/

或

/(\w+):(\w+)(?:\r\n)?/

【讨论】:

  • 谢谢,还在functions-online上测试过这些,但效果不太好,不知道为什么
【解决方案3】:

我认为你需要:

/([^:]+):([^\\r\\n]+)/
//__^ note the colon

【讨论】:

  • 谢谢,在 functions-online 上测试过,效果不太好,不知道为什么
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-02-10
相关资源
最近更新 更多