【问题标题】:Python unicode regex not working on big strings [duplicate]Python unicode正则表达式不适用于大字符串[重复]
【发布时间】:2017-02-24 15:54:07
【问题描述】:

由于某种原因,当在一个很大的 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 等)时,该函数会替换字符串的更大部分,但仍然不完整。

【问题讨论】:

  • 去掉re.UNICODE就可以了。
  • 哎呀,Python3和Python 2的字节串都没有问题……会不会是unicode层的Python 2 bug?
  • 这是您代码中的错误。 this one

标签: python regex string unicode


【解决方案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)
!Очень !Длинная !Строка. !Очень !Длинная !Строка. !Очень !Длинная !Строка. !Очень !Длинная !Строка. !Очень !Длинная !Строка. !Очень !Длинная !Строка. !Очень !Длинная !Строка. !Очень !Длинная !Строка. !Очень !Длинная !Строка. !Очень !Длинная !Строка. !Очень !Длинная !Строка. !Очень !Длинная !Строка. !Очень !Длинная !Строка. !Очень !Длинная !Строка.

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-06-06
    • 1970-01-01
    • 1970-01-01
    • 2017-01-23
    • 2022-08-19
    • 2016-01-28
    • 2015-03-30
    相关资源
    最近更新 更多