V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
likefly
V2EX  ›  程序员

求助一个正则的问题,急

  •  
  •   likefly · 336 天前 · 1415 次点击
    这是一个创建于 336 天前的主题,其中的信息可能已经有所发展或是发生改变。

    有一个报文:

    <?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  
       336 天前
    $2
    likefly
        2
    likefly  
    OP
       336 天前
    @sheeta 只能取到 789
    AoEiuV020CN
        3
    AoEiuV020CN  
       336 天前 via Android
    @likefly 举一反三,$1 就能得到 123 了,
    jsrunner
        4
    jsrunner  
       336 天前   ❤️ 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
       336 天前
    @AoEiuV020CN $1 只能取到外面括号的值
    sheeta
        6
    sheeta  
       336 天前
    @likefly 抱歉,是我的问题,这个只能取到最后一个匹配的
    likefly
        7
    likefly  
    OP
       336 天前
    @jsrunner 感谢,工作环境用不了代码,要怎么在编辑器里面直接替换出来 - -
    NoOneNoBody
        8
    NoOneNoBody  
       336 天前
    这个需要正则递归,python 内置 re 并不支持,sublimetext 也不能直接完成
    所以开个 console 按 #4 的方法手动吧

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

    $1-$2
    setsunakute
        23
    setsunakute  
       335 天前
    [^\d]+<id>|</id>[^\d]+ 替换为\n 即可
    setsunakute
        24
    setsunakute  
       335 天前
    [^\d]+<id>|</id>[^\d]+ 替换为-
    ns09005264
        25
    ns09005264  
       334 天前
    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  
       334 天前
    vim 里分三步,第一步把所有的`<tag>`替换为`-`,第二步把首尾的`-`去掉,第三步把连续的`---`替换为单个`-`
    ```
    :%s/\v(\<.{-}\>)/-/g
    :%s/\v(^-+|-+$)//g
    :%s/\v(-+)/-/g
    ```
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   3210 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 27ms · UTC 11:38 · PVG 19:38 · LAX 04:38 · JFK 07:38
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.