Python 正则表达式匹配无效的Unicode字符
我有这样的字符串:Python 正则表达式匹配无效的Unicode字符,python,regex,unicode,null,invalid-characters,Python,Regex,Unicode,Null,Invalid Characters,我有这样的字符串: ꐊ,ꀵ,\u0f6e,ⴗ,ꦚ,\u2d75,ꢯ,⾌,\97d乌克兰格里夫纳,⩱,ㇴ,\u2d6e,鼺,\x00Ꞁ 我想过滤掉所有这些以斜杠开头的无效字符,我正试图用Python中的正则表达式来实现这一点 它确实是这样工作的: re.sub(r",\u0f6e,", r",deleted,", s) 但不是这样: re.sub(r",\.{5},", r",deleted,", s) 它应该根据工作,所以我猜这是因为它们是无效字符?我怎样才能匹配它们 编辑:@metatoa
ꐊ,ꀵ,\u0f6e,ⴗ,ꦚ,\u2d75,ꢯ,⾌,\97d乌克兰格里夫纳,⩱,ㇴ,\u2d6e,鼺,\x00Ꞁ代码>
我想过滤掉所有这些以斜杠开头的无效字符,我正试图用Python中的正则表达式来实现这一点
它确实是这样工作的:
re.sub(r",\u0f6e,", r",deleted,", s)
但不是这样:
re.sub(r",\.{5},", r",deleted,", s)
它应该根据工作,所以我猜这是因为它们是无效字符?我怎样才能匹配它们
编辑:@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Ꞁ'
试试
re.sub(r“,\\.{5},”,r“,deleted,”,s)
是的,我试过了,只是出于好奇,为什么不显示为单个字符的Unicode字符无效?这些字符与由单个字符表示的Unicode字符相同,只是以不同的方式表示。打印字符串时可以看到结果字符,并且您的字体支持这些Unicode字符。我建议查看。OP的目标似乎是“过滤”无效字符。似乎根本不需要使用regexp,因为使用这些技术对字符串进行简单的循环就足够了。@jsbueno是的,我只是用一些过滤来重复OP的尝试。通过一些定时备份,'.join(['deleted'如果ud.category(c)[0]='c'否则c代表s中的c])
是最快的方法。