代码之家  ›  专栏  ›  技术社区  ›  Daniel Lawton

Regex:正则表达式中遇到无效的lookbehind断言[duplicate]

  •  0
  • Daniel Lawton  · 技术社区  · 6 年前

    这与其说是一个实际问题,不如说是一个理解问题。情况说明如下。我得到了两个引号“”之间的浮点数(例如一笔钱)。

    1. “1,23”
    2. “12,23”
    3. “123,23”

    (?<=\"[0-9]|[0-9]{2})(,)(?=[0-9]{2}\")
    

    我不完全理解的部分是结合or“|”的lookback。但让我们分开吧:

    (
    ?<=             //Start of the lookbehind
    \"              //Starting with an escaped quotation mark "
    [0-9]           //Followed by a digit between 0 and 9
    

    another stackoverflow问题。

    here :

    |[0-9]{2}       //Or followed by two digits between 0 and 9
    )
    

    有趣的是,它还匹配第三个示例“123,23”中的逗号。我真的不明白为什么。 我也不知道为什么我不必在or“|”运算符之后再加上起始引号,因为我认为在or运算符之前的完全查找需要修改或重复,例如:

    (?<=\"[0-9]|\"[0-9]{2})(,)(?=[0-9]{2}\")            //This however does not work at all
    

    (?<=\"[0-9]|\"[0-9]{2}|\"[0-9]{3})(,)(?=[0-9]{2}\")
    

    或者至少(如果有人能解释丢失的“\”):

    (?<=\"[0-9]|[0-9]{2}|[0-9]{3})(,)(?=[0-9]{2}\")
    

    我希望有人能帮助我了解情况。

    //编辑: 如果特别感兴趣,我在sublime text 3编辑器的常规文本文件中使用这个正则表达式来搜索逗号并替换它。

    0 回复  |  直到 7 年前
        1
  •  6
  •   ndnenkov    9 年前

    你说得对,

    (?<=\"[0-9]|\"[0-9]{2}|\"[0-9]{3})(,)(?=[0-9]{2}\")
    

    在这种情况下应该是正确的正则表达式。


    关于你为什么 “不需要 \" 两位数和三位数” -你真的需要它。
    (?<=\"[0-9]|[0-9]{2}|[0-9]{3})(,)(?=[0-9]{2}\")
    

    将匹配 12,23" 123,23"


    编辑 : 看起来问题是Sublime不允许可变的lookbehind长度,即使它们与 | . 意义 (?<=\"[0-9]|\"[0-9]{2}|\"[0-9]{3}) 会失败,因为备选方案的规模不同- .

    这是因为Sublime似乎在使用 Boost library 正则表达式。 There 声明如下:

    回头看

    (?<=pattern) 图案必须是固定长度的 ).

    (?<!pattern) 仅当模式无法与当前位置前面的字符匹配时,才会使用零个字符( 图案必须是固定长度的 ).

    另一种选择是将后面的人分开:

    (?:(?<=\"[0-9])|(?<=\"[0-9]{2})|(?<=\"[0-9]{3}))(,)(?=[0-9]{2}\")
    


    如果你不想列出所有可能的长度,你能做什么?

    有些regex引擎(包括Perl、Ruby和Sublime)中有一个很酷的技巧- \K . 什么 \千 大致翻译为 . 因此,您可以匹配任何 , 在一个被引号包围的浮点数内:

    "\d+\K,(?=\d+")
    

    See it in action