如何删除字符串中的所有逗号是合适的正则表达式:
12, 1425073747, "test", "1, 2, 3, ... "
结果:
12, 1425073747, "test", "1 2 3 ... "
我所拥有的正确匹配:
"((\d+), )+\d+"
然而,我显然不能用$ 1 $ 2取代它。我不能使用“\ d +,\ d +”,因为它会匹配12,1425073747,这不是我想要的。如果有人可以解释如何以递归方式解析出值得赞赏的值。
答案 0 :(得分:2)
这应该适合你:
>>> input = '12, 1425073747, "test", "1, 2, 3, ... "';
>>> print re.sub(r'(?!(([^"]*"){2})*[^"]*$),', "", input);
12, 1425073747, "test", "1 2 3 ... "
(?!(([^"]*"){2})*[^"]*$)
仅在引号内匹配文本 - 避免在逗号后匹配偶数引号。
答案 1 :(得分:0)
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'))
像这样,它在 < 1 秒内产生了想要的结果。最棘手的部分是找出如何将带有德语字符的字符串传递给 c++ 函数。当然,您可以使用任何您想要的编码。
答案 2 :(得分:-1)
您可以将re.sub
与简单的r'"[^"]*"'
正则表达式一起使用,并将match对象传递给可调用对象(用作替换参数),在其中您可以进一步操纵匹配项:
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)