【问题标题】:Searching in regex using backreference使用反向引用在正则表达式中搜索
【发布时间】:2020-09-09 16:04:27
【问题描述】:

嘿,所以我想使用正则表达式匹配 txt 文件中的多行 (Editpad Pro,Flavor java,它使用 RegexBuddy)

~Example 1
[POLYLINE]
Type=0x6
Label= ABC
CountryName=Singapore
Zip=12345
RoadID=38752
Data0=(3.39466,102.48391),(3.39435,102.48413)
Nod1=0,309594,0
Nod2=19,309595,0
[END]

~Example 2
[POLYLINE]
Type=0x6
Label=CBB
CountryName=MALAYSIA
Zip=26100
RoadID=27121
RouteParam=2,1,0,0,0,0,0,0,0,0,0,0
Data0=(3.85552,103.36551),(3.85532,103.36563)
Nod1=0,290397,0
Nod2=1,290105,0
[END]

我想使用反向引用来匹配 [POLYLINE] 到 RoadID 的原因是因为我想在这种情况下替换或添加因为我没有替换任何文本,只需在 RoadID 和 Data0 行之间添加 RouteParam,就像在 Example 2 中一样,所以我想编写将 [POLYLINE] 与 RoadID 匹配的代码,同时忽略那些已经具有 RouteParam 的代码,如示例 2 并添加 RoadID 和 Data0

线之间的 RouteParam

到目前为止,我使用的这段代码将与没有 RouteParam 的 POLYLINE 匹配并且它工作正常,但我想使用反向引用以便我可以替换

(\[POLYLINE\])(?:\r?\n(?!Type).*)*\r?\n(Type=0x6)(?:\r?\n(?!RoadID).*)*\r?\n(RoadID=.+)(?:\r?\n(?!RouteParam).*)

【问题讨论】:

    标签: regex


    【解决方案1】:

    您可以首先在匹配 [POLYLINE] 的第 1 组中捕获,然后匹配所有不以 RoadID 或 [END] 开头的行,然后匹配 RoadID

    然后断言下一行不以RouteParam=开头并匹配直到[END]第一次出现

    (\[POLYLINE](?:\r?\n(?!RoadID|\[END]).*)*\r?\nRoadID=.+\r?\n)((?:(?!RouteParam=|\[END]).*\r?\n)*\[END])
    
    • ( 捕获第 1 组
      • \[POLYLINE]匹配[POLYLINE]
      • (?:非捕获组
        • \r?\n(?!RoadID|\[END]).*如果不以 RoadID 或 [END] 开头,则匹配整行
      • )*关闭组并重复0+次
      • \r?\nRoadID=.+\r?\n 匹配以 RoadID= 开头的行
    • )关闭群
    • ( 捕获第 2 组
      • (?:非捕获组
        • (?!RouteParam=|\[END]).*\r?\n如果不以RouteParam或[END]开头,则匹配整行
      • )*关闭组并重复0+次
      • \[END]匹配[END]
    • )关闭群

    Regex demo

    在替换中,使用 2 个捕获组和要添加的 RouteParam。

    $1RouteParam=2,1,0,0,0,0,0,0,0,0,0,0\n$2
    

    【讨论】:

    • 嘿,谢谢,它可以工作,但我现在面临的问题是,如果你看示例 Type=0x6 在我正在处理的真实文件中,它具有不同的类型,例如 Type=0xe、Type0x7。所以你的代码可以工作,但它也与 Type=0x6 以外的其他类型匹配,所以我希望它只像示例一样找到 Type=0x6,谢谢 man
    • @JohnWeck 啊,我明白了,你的意思是这样的regex101.com/r/SbWbYD/1
    • 完全正确,嘿,非常感谢,感谢这个世界需要更多像你这样的人,尤其是新程序员,哈哈
    • 嘿,很抱歉这个老问题打扰你了> 在已经有 RouteParam 的部分,例如 RouteParam=2,0,0,0 替换为 RouteParam=2,1,0,0,谢谢!
    • @JohnWeck 这取决于你想保留多少规则,但你可以这样做regex101.com/r/psFt5y/1
    【解决方案2】:

    这是一种方法。对以下内容进行查找和替换:

    Find:    (\[POLYLINE\].*?RoadID=\d+)(.*?\[END\])
    Replace: $1\nRouteParam=2,1,0,0,0,0,0,0,0,0,0,0$2
    

    Demo

    请注意,上面的演示链接使用全点模式。如果你没有这个可用的,那么你可以使用[\s\S]* 而不是.* 来匹配可能的换行符。

    【讨论】:

      猜你喜欢
      • 2021-06-22
      • 2017-01-15
      • 2014-12-28
      • 2013-05-06
      • 1970-01-01
      • 1970-01-01
      • 2011-04-04
      • 1970-01-01
      • 2017-04-01
      相关资源
      最近更新 更多