Python unicode正则表达式不能处理大字符串

时间:2017-02-24 15:54:07

标签: python regex string unicode

出于某种原因,当在一个非常大的 unicode 字符串上使用re.sub时,该函数只查找并替换匹配的前半部分,忽略第二部分。 但是,当我减小字符串的大小(删除前半部分)时,它可以正常工作。 当我在ASCII字符串上测试相同时,它也可以正常工作。

任何人都可以帮我解决问题吗?

代码:

s = u"Очень Длинная Строка. Очень Длинная Строка. Очень Длинная Строка. Очень Длинная Строка. Очень Длинная Строка. Очень Длинная Строка. Очень Длинная Строка. Очень Длинная Строка. Очень Длинная Строка. Очень Длинная Строка. Очень Длинная Строка. Очень Длинная Строка. Очень Длинная Строка. Очень Длинная Строка."

# Find all capital letters, and add '!' before them
print re.sub(ur"([\u0410-\u042f])", ur"!\1", s, re.UNICODE)

结果:

!Очень !Длинная !Строка. !Очень !Длинная !Строка. !Очень !Длинная !Строка. !Очень !Длинная !Строка. !Очень !Длинная !Строка. !Очень !Длинная !Строка. !Очень !Длинная !Строка. !Очень !Длинная !Строка. !Очень !Длинная !Строка. !Очень !Длинная !Строка. !Очень !Длинная Строка. Очень Длинная Строка. Очень Длинная Строка. Очень Длинная Строка.

如您所见,字符串的最后一部分未经处理。

更新

正如RomanPerekhrest在下面发现的那样,当我们添加额外的标志(例如re.MULTILINE,re.VERBOSE等)时,该函数会替换字符串中较大的一部分,但仍然不满。

1 个答案:

答案 0 :(得分:1)

re.sub的函数签名在标志之前有一个计数:

re.sub(pattern, repl, string, count=0, flags=0)

您所看到的行为是因为您需要使用flags作为关键字参数,否则作为sub的第四个位置位置参数,它被视为计数。 (谢谢JF Sebastian。去投票他的answer

易于证明:

>>> re.sub(r'\d', '1', '0'*50, re.UNICODE)
'11111111111111111111111111111111000000000000000000'
>>> re.sub(r'\d', '1', '0'*50, re.M)
'11111111000000000000000000000000000000000000000000'

re.M的值为8,因此只进行了8次替换。纠正错误:

>>> re.sub(r'\d', '1', '0'*50, flags=re.M)
'11111111111111111111111111111111111111111111111111'

旁注:

PyPi regex module支持更强大的Unicode逻辑。

例如,如果要修改任何大写字母,可以使用\p{Lu}的元字符:

>>> s=u"Очень Длинная Строка. Очень Длинная Строка. Очень Длинная Строка. Очень Длинная Строка. Очень Длинная Строка. Очень Длинная Строка. Очень Длинная Строка. Очень Длинная Строка. Очень Длинная Строка. Очень Длинная Строка. Очень Длинная Строка. Очень Длинная Строка. Очень Длинная Строка. Очень Длинная Строка."
>>> import regex
>>> print regex.sub(ur"(\p{Lu})", ur"!\1", s)
!Очень !Длинная !Строка. !Очень !Длинная !Строка. !Очень !Длинная !Строка. !Очень !Длинная !Строка. !Очень !Длинная !Строка. !Очень !Длинная !Строка. !Очень !Длинная !Строка. !Очень !Длинная !Строка. !Очень !Длинная !Строка. !Очень !Длинная !Строка. !Очень !Длинная !Строка. !Очень !Длинная !Строка. !Очень !Длинная !Строка. !Очень !Длинная !Строка.