求助一个正则的问题,急 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
请不要在回答技术问题时复制粘贴 AI 生成的内容
likefly
V2EX    程序员

求助一个正则的问题,急

  •  
  •   likefly 2023-04-27 18:57:23 +08:00 2007 次点击
    这是一个创建于 897 天前的主题,其中的信息可能已经有所发展或是发生改变。

    有一个报文:

    <?xml><root><person><id>123</id></person><person><id>789</id></person></root> 

    只需要 <id></id> 标签中的的值,例如转换成 123-789,在 sumlime text 中要怎么替换呢,以下是我写的正则:

    <\?xml><root>(<person><id>(\d+)</id></person>)+</root> 

    替换的时候需要怎么处理呢

    26 条回复    2023-04-28 19:45:46 +08:00
    sheeta
        1
    sheeta  
       2023-04-27 18:58:06 +08:00
    $2
    likefly
        2
    likefly  
    OP
       2023-04-27 19:05:13 +08:00
    @sheeta 只能取到 789
    AoEiuV020CN
        3
    AoEiuV020CN  
       2023-04-27 19:08:35 +08:00 via Android
    @likefly 举一反三,$1 就能得到 123 了,
    jsrunner
        4
    jsrunner  
       2023-04-27 19:08:35 +08:00   1
    import re

    xml_str = '<?xml><root><person><id>123</id></person><person><id>789</id></person></root>'

    # 定义正则表达式模式,匹配 <id> 标签和其中的文本
    pattern = re.compile(r'<id>(.*?)</id>')

    # 使用 findall 方法查找所有匹配项,并返回匹配的文本列表
    matches = pattern.findall(xml_str)

    # 输出匹配的结果
    print(matches) # 输出 ['123', '789']
    likefly
        5
    likefly  
    OP
       2023-04-27 19:15:07 +08:00
    @AoEiuV020CN $1 只能取到外面括号的值
    sheeta
        6
    sheeta  
       2023-04-27 19:17:37 +08:00
    @likefly 抱歉,是我的问题,这个只能取到最后一个匹配的
    likefly
        7
    likefly  
    OP
       2023-04-27 19:18:06 +08:00
    @jsrunner 感谢,工作环境用不了代码,要怎么在编辑器里面直接替换出来 - -
    NoOneNoBody
        8
    NoOneNoBody  
       2023-04-27 19:20:54 +08:00
    这个需要正则递归,python 内置 re 并不支持,sublimetext 也不能直接完成
    所以开个 console 按 #4 的方法手动吧

    三方包 regex 支持递归
    mohumohu
        9
    mohumohu  
       2023-04-27 19:21:52 +08:00
    简单啊,你们就是把问题想复杂了,用什么正则,你直接把<root><person><id>替换成<root>,</id></person><person><id>替换成-,</id></person>替换成空不就好了吗
    likefly
        10
    likefly  
    OP
       2023-04-27 19:24:00 +08:00
    @NoOneNoBody 原来如此,我就是想递归,感谢
    Glauben
        11
    Glauben  
       2023-04-27 19:25:00 +08:00
    这种问题一律建议问 ChatGPT
    likefly
        12
    likefly  
    OP
       2023-04-27 19:26:08 +08:00
    @mohumohu 感谢,这确实是个好方法
    likefly
        13
    likefly  
    OP
       2023-04-27 19:27:08 +08:00
    @Glauben 落伍了,都没注册账号
    mmnnyycc
        14
    mmnnyycc  
       2023-04-27 20:15:59 +08:00
    (?<=<id>)[^<]+(?=</id>),这个 chatgpt 给的,一秒钟给出,还配合一个了一个 python 的代码
    mohumohu
        15
    mohumohu  
       2023-04-27 20:36:20 +08:00
    @mmnnyycc OP 问的是怎么替换,不是怎么匹配,就这个表达式都用不着 gpt 写
    weeei
        16
    weeei  
       2023-04-27 20:41:43 +08:00
    Regex: (.+)<id>(.+?)</id>(.+?)<id>(.+?)</id>(.+)
    With: $2 - $4
    Ericcccccccc
        17
    Ericcccccccc  
       2023-04-27 20:44:06 +08:00
    这种问题适合问 chatgpt
    busterian
        18
    busterian  
       2023-04-27 20:53:21 +08:00
    <id>(.+?)<\/id>
    <id>$1</id>
    mobbdeep
        19
    mobbdeep  
       2023-04-27 21:17:58 +08:00
    感觉 gpt 要吃掉不少爆栈或者 csdn 的份额啊
    jslang
        20
    jslang  
       2023-04-28 09:49:02 +08:00
    为什么用正则,这个解析 XML ,然后再拼接啊
    ruke
        21
    ruke  
       2023-04-28 10:01:49 +08:00
    ruke
        22
    ruke  
       2023-04-28 10:02:25 +08:00
    .*?(\d+).*?(\d+).*

    $1-$2
    setsunakute
        23
    setsunakute  
       2023-04-28 13:57:05 +08:00
    [^\d]+<id>|</id>[^\d]+ 替换为\n 即可
    setsunakute
        24
    setsunakute  
       2023-04-28 13:58:01 +08:00
    [^\d]+<id>|</id>[^\d]+ 替换为-
    ns09005264
        25
    ns09005264  
       2023-04-28 19:39:53 +08:00
    rust 里用 captures_iter 倒是可以轻松做到。
    ```
    let regex = Regex::new(r"<id>(\d+)</id>").unwrap();
    let str = "<?xml><root><person><id>123</id></person><person><id>456</id></person><person><id>789</id></person></root>";
    let result = regex
    .captures_iter(str)
    .map(|cap| cap[1].to_string())
    .collect::<Vec<_>>()
    .join("-");
    assert_eq!(result, "123-456-789");
    ```
    vim 里可以分多步处理
    ns09005264
        26
    ns09005264  
       2023-04-28 19:45:46 +08:00
    vim 里分三步,第一步把所有的`<tag>`替换为`-`,第二步把首尾的`-`去掉,第三步把连续的`---`替换为单个`-`
    ```
    :%s/\v(\<.{-}\>)/-/g
    :%s/\v(^-+|-+$)//g
    :%s/\v(-+)/-/g
    ```
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     3684 人在线   高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 26ms UTC 00:06 PVG 08:06 LAX 17:06 JFK 20:06
    Do have faith in what you're doing.
    ubao snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86