正则表达式匹配无效的 Unicode 字符
Regex match invalid Unicode characters
我有这样的字符串:
ꐊ,ꀵ,\u0f6e,ⴗ,ꦚ,\u2d75,ꢯ,⾌,\ua97d,⩱,ㇴ,\u2d6e,鼺,\x00Ꞁ
我想过滤掉所有这些以斜杠开头的无效字符,我正试图用 Python 中的正则表达式来做。
它确实是这样工作的:
re.sub(r",\u0f6e,", r",deleted,", s)
但不是这样的:
re.sub(r",\.{5},", r",deleted,", s)
它应该根据http://pythex.org工作,所以我猜是因为它们是无效字符?我怎样才能匹配它们?
编辑: @metatoaster 说我的问题不明确:
问题似乎是因为输入字符串 s
不是原始字符串。
>>> s = ' ꐊ,ꀵ,\u0f6e,ⴗ,ꦚ,\u2d75,ꢯ,⾌,\ua97d,⩱,ㇴ,\u2d6e,鼺,\x00Ꞁ'
>>> re.sub(r",\u0f6e,", r",deleted,", s)
' ꐊ,ꀵ,deleted,ⴗ,ꦚ,\u2d75,ꢯ,⾌,\ua97d,⩱,ㇴ,\u2d6e,鼺,\x00Ꞁ'
如果您的字符串确实按原样定义,我不明白您的第一个 re.sub
语句会如何工作。
>>> s = r' ꐊ,ꀵ,\u0f6e,ⴗ,ꦚ,\u2d75,ꢯ,⾌,\ua97d,⩱,ㇴ,\u2d6e,鼺,\x00Ꞁ'
>>> re.sub(r",\u0f6e,", r",deleted,", s)
' ꐊ,ꀵ,\u0f6e,ⴗ,ꦚ,\u2d75,ꢯ,⾌,\ua97d,⩱,ㇴ,\u2d6e,鼺,\x00Ꞁ'
请注意第一个 r'\u0f6e'
是如何保留下来的。在正则表达式中,\
字符也很特殊,因此也必须对其进行转义。这可以通过使用 \
来完成。现在尝试:
>>> re.sub(r",\u0f6e,", r",deleted,", s)
' ꐊ,ꀵ,deleted,ⴗ,ꦚ,\u2d75,ꢯ,⾌,\ua97d,⩱,ㇴ,\u2d6e,鼺,\x00Ꞁ'
为了匹配实际的表达式并且不超过必要,请注意 \u
序列在 0-9
和 a-f
之间恰好有 4 个后续字符。不要尝试匹配任何 5 个字符,而是更具体,例如:
>>> re.sub(r",\u[0-9a-f]+,", r",deleted,", s)
' ꐊ,ꀵ,deleted,ⴗ,ꦚ,deleted,ꢯ,⾌,deleted,⩱,ㇴ,deleted,鼺,\x00Ꞁ'
请注意,整个答案假定您提供给我们的信息是正确的,并且转义序列实际上是反斜杠字符。更新您的问题以包含这些代码片段将很有用,就像我在这里所做的那样,以减少对正在完成的事情的歧义(因为我们可以复制粘贴您的代码并 运行 它以查看出了什么问题,我们可以也更容易纠正它)。
您的字符串似乎包含未定义的 Unicode 代码点。 \u0f6e
是一个 单代码点 表示为转义码。示例:
>>> s = 'ꐊ,ꀵ,\u0f6e,ⴗ,ꦚ,\u2d75,ꢯ,⾌,\ua97d,⩱,ㇴ,\u2d6e,鼺,\x00Ꞁ'
>>> s
'ꐊ,ꀵ,\u0f6e,ⴗ,ꦚ,\u2d75,ꢯ,⾌,\ua97d,⩱,ㇴ,\u2d6e,鼺,\x00Ꞁ'
>>> print(s)
ꐊ,ꀵ,,ⴗ,ꦚ,,ꢯ,⾌,,⩱,ㇴ,,鼺, Ꞁ
注意打印字符串如何将字符显示为未定义的框。它显示为用于调试目的的转义码。这些代码点有一些共同点。根据 Unicode 数据库,它们是 C 类(控制)代码点。他们也没有名字。一个快速过滤的方法是:
>>> ''.join(['deleted' if ud.category(c)[0] == 'C' else c for c in s])
'ꐊ,ꀵ,deleted,ⴗ,ꦚ,deleted,ꢯ,⾌,deleted,⩱,ㇴ,deleted,鼺,deletedꞀ'
我有这样的字符串:
ꐊ,ꀵ,\u0f6e,ⴗ,ꦚ,\u2d75,ꢯ,⾌,\ua97d,⩱,ㇴ,\u2d6e,鼺,\x00Ꞁ
我想过滤掉所有这些以斜杠开头的无效字符,我正试图用 Python 中的正则表达式来做。
它确实是这样工作的:
re.sub(r",\u0f6e,", r",deleted,", s)
但不是这样的:
re.sub(r",\.{5},", r",deleted,", s)
它应该根据http://pythex.org工作,所以我猜是因为它们是无效字符?我怎样才能匹配它们?
编辑: @metatoaster 说我的问题不明确:
问题似乎是因为输入字符串 s
不是原始字符串。
>>> s = ' ꐊ,ꀵ,\u0f6e,ⴗ,ꦚ,\u2d75,ꢯ,⾌,\ua97d,⩱,ㇴ,\u2d6e,鼺,\x00Ꞁ'
>>> re.sub(r",\u0f6e,", r",deleted,", s)
' ꐊ,ꀵ,deleted,ⴗ,ꦚ,\u2d75,ꢯ,⾌,\ua97d,⩱,ㇴ,\u2d6e,鼺,\x00Ꞁ'
如果您的字符串确实按原样定义,我不明白您的第一个 re.sub
语句会如何工作。
>>> s = r' ꐊ,ꀵ,\u0f6e,ⴗ,ꦚ,\u2d75,ꢯ,⾌,\ua97d,⩱,ㇴ,\u2d6e,鼺,\x00Ꞁ'
>>> re.sub(r",\u0f6e,", r",deleted,", s)
' ꐊ,ꀵ,\u0f6e,ⴗ,ꦚ,\u2d75,ꢯ,⾌,\ua97d,⩱,ㇴ,\u2d6e,鼺,\x00Ꞁ'
请注意第一个 r'\u0f6e'
是如何保留下来的。在正则表达式中,\
字符也很特殊,因此也必须对其进行转义。这可以通过使用 \
来完成。现在尝试:
>>> re.sub(r",\u0f6e,", r",deleted,", s)
' ꐊ,ꀵ,deleted,ⴗ,ꦚ,\u2d75,ꢯ,⾌,\ua97d,⩱,ㇴ,\u2d6e,鼺,\x00Ꞁ'
为了匹配实际的表达式并且不超过必要,请注意 \u
序列在 0-9
和 a-f
之间恰好有 4 个后续字符。不要尝试匹配任何 5 个字符,而是更具体,例如:
>>> re.sub(r",\u[0-9a-f]+,", r",deleted,", s)
' ꐊ,ꀵ,deleted,ⴗ,ꦚ,deleted,ꢯ,⾌,deleted,⩱,ㇴ,deleted,鼺,\x00Ꞁ'
请注意,整个答案假定您提供给我们的信息是正确的,并且转义序列实际上是反斜杠字符。更新您的问题以包含这些代码片段将很有用,就像我在这里所做的那样,以减少对正在完成的事情的歧义(因为我们可以复制粘贴您的代码并 运行 它以查看出了什么问题,我们可以也更容易纠正它)。
您的字符串似乎包含未定义的 Unicode 代码点。 \u0f6e
是一个 单代码点 表示为转义码。示例:
>>> s = 'ꐊ,ꀵ,\u0f6e,ⴗ,ꦚ,\u2d75,ꢯ,⾌,\ua97d,⩱,ㇴ,\u2d6e,鼺,\x00Ꞁ'
>>> s
'ꐊ,ꀵ,\u0f6e,ⴗ,ꦚ,\u2d75,ꢯ,⾌,\ua97d,⩱,ㇴ,\u2d6e,鼺,\x00Ꞁ'
>>> print(s)
ꐊ,ꀵ,,ⴗ,ꦚ,,ꢯ,⾌,,⩱,ㇴ,,鼺, Ꞁ
注意打印字符串如何将字符显示为未定义的框。它显示为用于调试目的的转义码。这些代码点有一些共同点。根据 Unicode 数据库,它们是 C 类(控制)代码点。他们也没有名字。一个快速过滤的方法是:
>>> ''.join(['deleted' if ud.category(c)[0] == 'C' else c for c in s])
'ꐊ,ꀵ,deleted,ⴗ,ꦚ,deleted,ꢯ,⾌,deleted,⩱,ㇴ,deleted,鼺,deletedꞀ'