正则表达式保留指定字符问题:星号丢失与日期格式匹配失败
问题分析与解决
你的问题出在正则表达式的字符集写法上,咱们一步步拆解:
原正则的问题
你最初用的[^0-9^a-z^A-Z^.^,^/^-]其实有个误区:字符集里的^只有放在最开头时才是“取反”的意思,中间的^会被当成普通字符来处理。所以这个正则实际是在排除:数字、^符号、大小写字母、.、,、/、-——但星号*不在允许列表里,自然会被替换成空格,这就是为什么iban: es45 **** **** 1234 5678 9012里的星号会消失。
添加星号后出错的原因
你改成[^0-9^a-z^A-Z^.^,^/^-^*]时,又引入了新问题:字符集里的^-*会被解析成ASCII范围(^的ASCII是94,-是45,*是42),这就导致这个范围里的大量字符被错误排除,包括日期里的-(因为-本身被包含在这个奇怪的范围逻辑里了),所以16-01-2107这类格式就处理失败了。
正确的正则写法
把字符集里多余的^都去掉,只保留开头的取反符号,然后把允许的字符直接列出来,同时注意把-放在字符集的末尾(避免被当成范围符号):
re.sub('[^0-9a-zA-Z.,/-*]', ' ', line)
或者更清晰的写法(把-放末尾):
re.sub('[^0-9a-zA-Z.,/*-]', ' ', line)
这样就同时允许了星号*和连字符-,不会误删IBAN里的星号,也能正确保留日期格式里的-了。
验证示例
- 处理
iban: es45 **** **** 1234 5678 9012:星号会被保留,其他非法字符(比如冒号)被替换成空格,结果是iban es45 **** **** 1234 5678 9012 - 处理
16-01-2107:连字符完全保留,结果还是16-01-2107
内容的提问来源于stack exchange,提问作者crossmax
相关产品推荐
相关产品推荐

