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

Python正则表达式非捕获组

  •  1
  • AngiSen  · 技术社区  · 6 年前

    我正在尝试理解re.split()函数,该函数使用非捕获组来拆分逗号分隔的字符串。

    这是我的代码:

     pattern = re.compile(r',(?=(?:"[^"]*")*[^"]*$)')
     text = 'qarcac,"this is, test1",123566'
     results= re.split(pattern, text)
     for r in results:
        print(r.strip())
    

    当我执行此代码时,结果与预期一致。

    拆分1 :卡塔尔

    拆分2 :“这是,测试1”

    拆分3 :123566

    然而,如果我在源文本中再添加一个双引号字符串,它就不能按预期工作。

    text = 'qarcac,"this is, test1","this is, test2", 123566, testdata'
    

    并产生以下输出

    拆分1 :qarcc,“这是,测试1”

    拆分2 :“这是,测试2”

    拆分3 :123566

    有人能解释一下这里发生了什么,在这两种情况下,非抓捕组的工作方式有什么不同吗?

    1 回复  |  直到 6 年前
        1
  •  1
  •   melpomene    6 年前

    这与(非)捕获组无关。

    (?:"[^"]*")*[^"]*$ 比赛:

    • "[^"]*" -带引号的字符串(两个引号之间有0个或多个非引号)
    • (?: ... )* -0个或多个带引号的字符串
    • [^"]* -后跟0个或多个非引号
    • $ -后跟字符串结尾

    换句话说,这个正则表达式匹配如下内容 "foo""bar""baz"otherstuff .

    在第一个示例中,目标字符串是:

    qarcac,"this is, test1",123566
           ^^^^^^^^^^^^^^^^^^^^^^^
    

    我在上面的regex匹配的部分下了下划线(一个带引号的部分后面跟着一个带引号的尾部,后面跟着字符串的结尾)。

    在第二个示例中,目标字符串是:

    qarcac,"this is, test1","this is, test2", 123566, testdata
                            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    

    我再次强调了regex匹配的部分。

    第一个引用的部分由于逗号而不匹配:

    "this is, test1","this is, test2"
                    X
    

    "foo","bar" 不匹配,因为正则表达式要求引用的部分彼此相邻,如 "foo""bar" ,中间没有任何东西。


    如果您只想确保每个匹配的逗号都在被引用的部分之外(即后跟偶数个引号),您可以简单地使用

    ,(?=[^"]*(?:"[^"]*"[^"]*)*$)
    

    作为你的regex。