V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
itskingname
V2EX  ›  正则表达式

正则表达式如何忽略子字符串中的内容

  •  
  •   itskingname · 2022-11-15 11:20:05 +08:00 · 1108 次点击
    这是一个创建于 769 天前的主题,其中的信息可能已经有所发展或是发生改变。

    我有一批字符串,他们的格式是这样的:

    a = 'abc[账号]def[密码]xyz'
    
    b = 'aaa[账号]还有"子字符串[无效内容]子字符串"bbb[密码]zzz'
    

    我想提取所有中括号里面的内容,但忽略双引号内部的中括号中的内容。

    以上面两个字符串 a 和 b 为例,需要提取的内容都是『账号』和『密码』

    目前我能想到的办法是使用状态机来做。请问有没有使用正则表达式就能实现的方法?

    12 条回复    2023-05-30 14:51:10 +08:00
    youdoit
        1
    youdoit  
       2022-11-15 11:31:39 +08:00
    [ ^\[\] ]
    itskingname
        2
    itskingname  
    OP
       2022-11-15 11:33:35 +08:00
    @youdoit 你这个怎么忽略双引号呢?
    youdoit
        3
    youdoit  
       2022-11-15 11:52:30 +08:00
    @itskingname 代码做到,比如把[ ]替换成空
    Hylenbin
        4
    Hylenbin  
       2022-11-15 11:59:14 +08:00 via iPhone
    用正则的“断言”应该就可以实现
    Hylenbin
        5
    Hylenbin  
       2022-11-15 12:04:30 +08:00 via iPhone
    接上,给个不严谨的例子供参考,(?<!”.*)([.*])(?!”.*)
    my8100
        6
    my8100  
       2022-11-15 12:52:56 +08:00 via iPhone
    “忽略双引号内部的中括号中的内容”,既然这么明确,为啥不先 re.sub 一次将无关内容替换为空字符串?
    Pipecraft
        7
    Pipecraft  
       2022-11-15 14:18:27 +08:00
    这段正则表达式也许可以


    ```js
    function findMatched(str) {
    const matched = [];
    str.replace(/"[^"]+"|(\[[^\[\]"]+\])/g, (a, b) => {
    if (b) {
    matched.push(b);
    }
    });
    return matched;
    }

    a = "abc[账号]def[密码]xyz";

    b = 'aaa[账号]还有"子字符串[无效内容]子字符串"bbb[密码]zzz';

    c = 'a"a[a]a"a[账号]还有"子字符串[无效内容]子字符串"bbb[密码]z"zz[其他]abcd';

    console.log(findMatched(a));
    console.log(findMatched(b));
    console.log(findMatched(c));
    ```
    Pipecraft
        8
    Pipecraft  
       2022-11-15 14:22:31 +08:00
    @Pipecraft #7
    上面那段正则稍微修改一点。
    ```js
    /"[^"]*"|(\[[^\[\]]+\])/g
    ```
    ezking
        9
    ezking  
       2022-11-15 15:19:11 +08:00
    /(?<!".*?)\[[^\[\]]*?\]|\[[^\[\]]*?\](?!.*?")/g
    拿去用吧
    ezking
        10
    ezking  
       2022-11-15 15:23:05 +08:00
    不过最好去除("xxx") 再找内容
    itskingname
        11
    itskingname  
    OP
       2022-11-15 15:33:07 +08:00
    @my8100 因为我是要把外层的[xxx]替换成其他内容,子字符串中的内容不动。
    temberature
        12
    temberature  
       2023-05-30 14:51:10 +08:00
    Model: GPT-4

    User
    输入:```abc[tember]def[134523]xyz
    aaa[tiandatong]还有"子字符串[无效内容]子字符串"bbb[324512]zzz```
    预期输出结果:```tember 134523
    tiandatong 324512```
    - 使用 JavaScript 写正则表达式替换文本
    - 基于状态机的思路,进行模式的切换和循环

    ChatGPT
    在这个问题中,你想要的似乎是在两个方括号之间提取内容,并且这些方括号之间的内容是指定的字符串,或者方括号之后有一段特定的数字。

    我们可以使用 JavaScript 中的正则表达式来做到这一点。以下是一种可能的解决方案,基于状态机的思路,进行模式的切换和循环:

    javascript
    Copy code
    let input = `abc[tember]def[134523]xyz
    aaa[tiandatong]还有"子字符串[无效内容]子字符串"bbb[324512]zzz`;

    let keywordReg = /\[([a-z]+)\]|(\[([0-9]+)\])/gim;

    let expectedOutput = "";
    let keywordFlag = false;

    input.replace(keywordReg, function(match, p1, p2, p3) {
    if (p1) {
    if (keywordFlag) {
    expectedOutput += " ";
    }
    expectedOutput += p1;
    keywordFlag = true;
    } else if (p3) {
    if (keywordFlag) {
    expectedOutput += " " + p3;
    expectedOutput += "\n";
    keywordFlag = false;
    }
    }
    });

    console.log(expectedOutput.trim());
    这段代码首先定义了一个正则表达式,用于在输入字符串中匹配两种模式,一种是在方括号内包含一个或多个小写字母的模式,另一种是在方括号内包含一个或多个数字的模式。

    然后,代码使用 replace 方法,这个方法接受一个正则表达式和一个回调函数。对于输入字符串中的每一个匹配,它都会调用这个回调函数。在回调函数中,我们检查每个匹配项,如果匹配项是一个关键词(即在方括号内包含字母),我们将其添加到预期的输出字
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1828 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 16:17 · PVG 00:17 · LAX 08:17 · JFK 11:17
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.