代码之家  ›  专栏  ›  技术社区  ›  hobbes3

Regex创建两个捕获组,其中第二个捕获多次

  •  1
  • hobbes3  · 技术社区  · 7 年前

    我的测试字符串是

    thread_id=1152236, geo_locality.nomv="Seattle|||San Francisco|||Chicago", user_reference_count=0
    

    有没有可能 正则表达式 捕获组,其中第二个捕获组将捕获多次?

    我要第一个抓捕小组抓捕 geo_locality (没有硬编码)和要捕获的第二个捕获组 Seattle , San Francisco ,和 Chicago .

    我最近得到的是

    (?<key>\w+)\.nomv="(?<val>.+?)(?=\|\|\||")
    

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

    除了 val 抓捕组还需要抓捕其他城市。

    3 回复  |  直到 7 年前
        1
  •  2
  •   wp78de    7 年前

    答案取决于游戏中的regex口味。

    1. 使用 \G 在上一场比赛结束时继续使用PCRE

      (?<key>\w+)\.nomv="|(?!^)(?<=\G)(?<val>.+?)(?:\|\|\||")
      

      Demo

      这个 \克 锚可以是一个有点神秘和真正的魔法在同一时间。

    说明:

    • (?<key>\w+)\.nomv="| 第一个替换中的键和文字用作起始锚
    • 这个 \克 锚点断言上一个匹配的结束位置或第一个匹配的字符串的开始位置。

      • 排除我添加的字符串的开头 (?!^) 在之前阻止匹配 nom=" ).
      • (?<=\G) 所以,我们只能在之前有比赛的情况下继续
      • (?<val>.+?) 根据需要捕获每个城市街区
      • (?:\|\|\||") 非捕获组仅用于向前移动光标

    1. 在.NET中使用捕获

      (?<_KEY_1>\w+)\.nomv="(?:(?<_VAL_1>.+?)(?:\|\|\||"))*
      

      Demo

      这对.NET来说不是真正的挑战。只需在周围添加一个组和一个量词,然后 (?<val>) 多次匹配。然后,从 Captures .

    enter image description here

        2
  •  1
  •   The fourth bird    7 年前

    你可以用一个 alternation 如果支持的话 (?<=

    (?<_KEY_1>\w+)(?=\.nomv=")|(?<_VAL_1>(?<=\.nomv=")[A-Za-z ]+|(?<=\|\|\|)[A-Za-z ]+)

    解释

    • (?<_KEY_1> 命名捕获组
      • \w+ 匹配一个或多个单词字符
    • ) 关闭命名捕获组
    • (?=\.nomv=") 积极的展望,断言接下来是 .nomv="
    • | 或者
    • (?<_VAL_1> 命名捕获组
      • (?<=\.nomv=") 肯定地说左边的是 .nomv=
      • [A-Za-z ]+ 匹配大写、小写或空白
      • | 或者
      • (?<=\|\|\|) 肯定地说左边的是 |||
      • [A-Za-z]+ 匹配大写、小写或空白
    • ) 关闭命名捕获组
        3
  •  0
  •   Michał Turczyn    7 年前

    尝试以下模式: (?<_KEY_1>\w+)\.nomv="(?<_VAL_1>(.+?\|\|\|)+.+)" .

    需要注意的是,在捕获组内部 _VAL_1 可以有更多的捕捉组,但是 _瓦卢1 是你需要的。

    DEMO.

    推荐文章