【问题标题】:Regex : Remove all commas between a quote separated string [python] [duplicate]正则表达式:删除引号分隔字符串之间的所有逗号 [python] [重复]
【发布时间】:2015-02-27 21:58:55
【问题描述】:

什么是适当的正则表达式来删除字符串中的所有逗号:

12, 1425073747, "test", "1, 2, 3, ... "

结果:

12, 1425073747, "test", "1 2 3 ... "

我所拥有的正确匹配:

"((\d+), )+\d+"

但是,我显然不能用 $1 $2 代替它。我不能使用 "\d+, \d+" 因为它会匹配 12, 1425073747 这不是我想要的。如果有人可以解释如何递归地解析出值,那也将不胜感激。

【问题讨论】:

    标签: python regex regex-negation


    【解决方案1】:

    这应该适合你:

    >>> input = '12, 1425073747, "test", "1, 2, 3, ... "';
    >>> print re.sub(r'(?!(([^"]*"){2})*[^"]*$),', "", input);
    12, 1425073747, "test", "1 2 3 ... "
    

    (?!(([^"]*"){2})*[^"]*$) 仅在引号内匹配文本 - 避免匹配逗号后的偶数个引号。

    【讨论】:

      【解决方案2】:

      您可以将re.sub 与简单的r'"[^"]*"' 正则表达式一起使用,并将匹配对象传递给用作替换参数的可调用对象,您可以在其中进一步操作匹配:

      import re
      text = '12, 1425073747, "test", "1, 2, 3, ... "'
      print( re.sub(r'"[^"]*"', lambda x: x.group().replace(",", ""), text) )
      

      请参阅Python demo

      如果引号之间的字符串可能包含转义引号,请使用

      re.sub(r'(?s)"[^"\\]*(?:\\.[^"\\]*)*"', lambda x: x.group().replace(",", ""), text)
      

      这里,(?s)re.S / re.DOTALL 标志的内联版本,其余的是双引号字符串文字匹配模式。

      奖金

      • 删除双引号之间的所有空格:re.sub(r'"[^"]*"', lambda x: ''.join(x.group().split()), text)
      • 删除双引号内的所有非数字字符:re.sub(r'"[^"]*"', lambda x: ''.join(c for c in x.group() if c.isdigit()), text)
      • 删除双引号内的所有数字字符:re.sub(r'"[^"]*"', lambda x: ''.join(c for c in x.group() if not c.isdigit()), text)

      【讨论】:

        【解决方案3】:

        anubhava 提供的解决方案非常有用,实际上是我发现的指南中唯一有效的解决方案 - 这意味着真正可靠地删除了引用文本中的分号。但是,在 640 kB 的文本文件(是的,640)上使用它需要大约 3 分钟,即使在旧的 i5 上也是不可接受的。

        我的解决方案是实现一个 C++ 函数:

        #include <string>
        #include <cstring>
        #include <iostream>
        
        using namespace std;
        
        extern "C" // required when using C++ compiler
            const char *
            erasesemi(char *s)
        {
            bool WeAreIn = false;
            long sl = strlen(s);
            char *r = (char*) malloc(sl+1);
            strcpy(r, s);
            for (long i = 0; (i < (sl - 1)); i++)
            {
                if (s[i] == '"')
                {
                    WeAreIn = not(WeAreIn);
                }
                if ((s[i] == ';') & WeAreIn)
                {
                    r[i] = ',';
                }
                else
                {
                    r[i] = s[i];
                }
            }
            return r;
        }
        

        根据我在互联网上的发现,我使用了这个 setup.py

        from setuptools import setup, Extension
        
        # Compile *mysum.cpp* into a shared library
        setup(
            # ...
            ext_modules=[Extension('erasesemi', ['erasesemi.cpp'],), ],
        )
        

        之后你必须运行

        python3 setup.py build
        

        主代码中的相应行是:

        import ctypes
        import glob
        libfile = glob.glob(
            'build/lib.linux-x86_64-3.8/erasesemi.cpython-38-x86_64-linux-gnu.so')[0]
        
        mylib = ctypes.CDLL(libfile)
        
        mylib.erasesemi.restype = ctypes.c_char_p
        mylib.erasesemi.argtypes = [ctypes.c_char_p]
        
        ..
        
        data3 = mylib.erasesemi(str(data2).encode('latin-1'))
        

        像这样,它在

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2016-01-24
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-12-12
          • 2020-05-06
          相关资源
          最近更新 更多