【问题标题】:everything, but everything between [ and ]一切,但 [ 和 ] 之间的一切
【发布时间】:2010-01-06 20:36:28
【问题描述】:

我正在尝试匹配所有内容,但是 [ 和 ] 之间的所有内容。

[ 和 ] 之间的一切都是

\[.+\]

一切,但 [ 和 ] 之间的一切都是

[^(\[.+\])]+

搜索文本是

valid[REGEX_EMAIL|REGEX_PASSWORD|REGEX_TEST]

它匹配“有效”和“REGEX_EMAIL|REGEX_PASSWORD|REGEX_TEST”。

它应该匹配“有效”,但不匹配“REGEX_EMAIL|REGEX_PASSWORD|REGEX_TEST”。

如何解决?

我希望我的 php 验证类和 CodeIgniter 一样...

【问题讨论】:

  • 方括号可以嵌套吗?如果没有,你最好把它们去掉,然后匹配剩下的。
  • 由于是PCRE相关的,可以使用\[[^][]*](*SKIP)(*F)|(?:[^[]|\[(?![^][]*]))+(demo)。

标签: php regex codeigniter


【解决方案1】:

[^(\[.+\])]+ 并不是你想的那样。

从字面上看,它的意思是“匹配任何字符,除了 any 其中一个或多个 ()[.+]。”

[] 是一个字符集,与该集中的一个字符匹配(如果它以 ^ 开头,则不匹配)

【讨论】:

    【解决方案2】:

    我相信您会在所谓的否定前瞻中找到答案。它允许您在搜索中包含模式,而无需将它们实际包含在匹配中。

    /^.*(?!\[.+\])$/
    

    (?! ... ) 是负前瞻部分。

    【讨论】:

    • 我在 Regex Tester 的 regexpal.com 和 Komodo IDE 的 Rx Toolkit 中测试了您的建议,但没有成功 :-(
    • 我很抱歉。这是我第一次需要使用它,但这实际上是积极前瞻的情况(?=我想你会发现现在匹配:)
    • 为了让它在正则表达式中工作,这里是实际的正则表达式:.*(?=[.+])
    【解决方案3】:

    根据您使用的数据尝试此操作 'valid[REGEX_EMAIL|REGEX_PASSWORD|REGEX_TEST]'

    ^[^[]+   
    

    它将返回“有效”。

    根据您使用的语言,您可能需要转义 [,所以这样写 ^[^\[]+

    此正则表达式假定 [REGEX_EMAIL|REGEX_PASSWORD|REGEX_TEST] 前面的文本中永远不会有“[”

    我使用 Eric Gunnerson 的 RegexWorkbench for .NET 对此进行了测试

    【讨论】:

      【解决方案4】:
      $string = 'valid[REGEX_EMAIL|REGEX_PASSWORD|REGEX_TEST]';
      
      preg_match('#(\S+)\[.+?\]#', $string, $match);
      
      echo $match[1];
      

      【讨论】:

      • 你必须让它变得不贪婪,或者用[^\]]替换.
      • 你是对的,尽管根据输入文本可能不需要它。
      【解决方案5】:

      我已经查看了CI's Validation class的源代码。

      它们允许像这样设置规则

      array('field' => "valid|length[5]|foo|callback_bar")
      

      我没有看到任何嵌套的方括号或方括号内的管道。 Docs 明确表示,您可能只有一个参数。该字符串在内部设置为$_rules。验证时,字符串将首先将exploded 放入一个数组中,因此上面的计算结果为四个$rules。

      'field' => array('valid', 'length[5]', 'foo', 'callback_bar')
      

      然后他们遍历数组,检查$rule 是否是substr() 的回调。然后他们检查$rule 中是否有带有"/(.*?)\[(.*?)\]/" 模式的方括号,如果有,将其从$rule 中取出,并将方括号的内部部分存储为$param。最后,他们只是将$rule 作为带有检测到的参数的变量函数执行,例如$rule(POST[$field], 5);

      如您所见,他们并没有一次性拆分所有内容。这并不能回答您的问题,但了解 CI 的内部逻辑以使其 Validator 运行可能会帮助您重新考虑您的方法。

      意见:我想补充一点,他们的做法很糟糕。验证者链是Command Pattern 的主要候选者。当然,用小而紧凑的字符串来指定验证器是很好的,但是当涉及到实际运行链时,你会付出很多丑陋的字符串杂耍来支付这个费用。看看Zend Framework是怎么做的或者看看PHPs native filter functions。

      【讨论】:

        【解决方案6】:

        如果我理解正确的话,这是三种不同的文本:

        1. 从开始到第一个 [
        2. 在一个]和一个[之间
        3. 从最后一个]到最后

        鉴于此,每个都有一个正则表达式:

        1. ^([^\x5B]*)[
        2. ]([^\x5B\x5D]*)[
        3. ]([^\x5D]*)$

        (x5B 和 x5D 是左右括号的十六进制转义。)请注意,整个表达式的匹配将包括标记边界的括号;子表达式 1 给出不包括括号的匹配项。

        【讨论】:

        • 可能是最不可读的写法,不知道为什么要使用十六进制代码作为简单的方括号。
        • 明白了——如果你愿意的话,你同样可以使用 \[ 和 \] 作为括号字符。我发现比尝试区分给定括号是否真的关闭字符类或用作文字更容易。使用可识别正则表达式的语法荧光笔,这不会成为问题,使用 \[ 和 \] 会更好。
        【解决方案7】:

        尝试积极的前瞻断言(它本身不会被捕获)

        ^.*(?=\[.+\])
        

        【讨论】:

          【解决方案8】:

          当有Regex Tester 时,您不必精通正则表达式。只需输入一些测试数据并使用正则表达式,直到获得所需的结果。右侧还有快速参考可帮助您。

          嗯,至少我是这样对待他们的。

          【讨论】:

            猜你喜欢
            • 2014-07-25
            • 1970-01-01
            • 2018-12-07
            • 2014-02-02
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2013-06-18
            • 1970-01-01
            相关资源
            最近更新 更多