正则表达式返回 true 且日文字符不正确
regex returning true with incorrect Japanese characters
我正在检查表格,是否输入了符合日文格式的邮政编码。
我今天意识到有些信息通过了,即使它不应该 "passed" 正则表达式匹配测试。
这是正则表达式:
".*([0-90-9]{3}[-ー]{1}[0-90-9]{4}).*"
包括普通数字和日文数字(“-”也一样,日文“ー”也可以输入),格式应该是这样的:
123-4567.
当只输入拉丁字母和数字时,它工作正常。
但是一些根本不匹配的日语字符......被return编辑为匹配:
(注意:匹配会 return 一些东西,不匹配将 return 什么都没有。)
>>> import re
>>> regstr = ".*([0-90-9]{3}[-ー]{1}[0-90-9]{4}).*"
>>> re.match( regstr, "this is obviously not going to work")
>>> re.match( regstr, "this is going to work 123-4567")
<_sre.SRE_Match object at 0x7fced8b485d0>
>>> re.match( regstr, "this is going to work too 123ー4567")
<_sre.SRE_Match object at 0x7fced8b48648>
>>> re.match( regstr, "This will not work, as it should not : 1234-567")
>>> re.match( regstr, "This should not work, but it does : 1234ー567")
<_sre.SRE_Match object at 0x7fced8b48648>
>>> re.match( regstr, "Now just seems crazy ....... 京都府")
<_sre.SRE_Match object at 0x7fced8b485d0>
>>> re.match( regstr, "京都府")
<_sre.SRE_Match object at 0x7fced8b48648>
>>> "京都府"
'\xe4\xba\xac\xe9\x83\xbd\xe5\xba\x9c'
>>> re.match( regstr, "\xe4\xba\xac\xe9\x83\xbd\xe5\xba\x9c")
<_sre.SRE_Match object at 0x7fced8b48648>
我尝试输入汉字,输入的两个字符不匹配。
所以居住在京都府的任何人...都可以 "bypass" 似乎是正则表达式,因为“京都府”足以使整个字符串有效。
这三个字符中只有两个不起作用。
我尝试了这三个字符的 unicode 代码,它也匹配(我想知道是否可以使用代码而不是字符本身来解析字符串,并想确保它没有'它包含实际上适合“000-0000”的内容。它没有,但它仍然匹配正则表达式)。
住在东京“东京府”的人会'less'幸运哈哈:
>>> re.match( regstr, "東京府")
>>> "東京府"
'\xe6\x9d\xb1\xe4\xba\xac\xe5\xba\x9c'
我在那里检查过:https://regex101.com/ 而那 3 个字符没有
所以...我在这里几乎迷路了。
使用更简单的“.([0-9]{3}[-]{1}[0-9]{4}).”作为正则表达式,它似乎是很好,但我真的不想限制用户只输入 [0-9-],因为很多人会输入日文版本 01234566789ー(更长)。
如果重要:
# 'Japanese numbers' code
>>> "0123456789ー"
'\xef\xbc\x90\xef\xbc\x91\xef\xbc\x92\xef\xbc\x93\xef\xbc\x94\xef\xbc\x95\xef\xbc\x96\xef\xbc\x97\xef\xbc\x98\xef\xbc\x99\xe3\x83\xbc'
我现在只是将日文0123456798ー转换为0123456789-,并应用一个完全不包含日文字符的正则表达式,但是......我真的很想知道正则表达式和日文是怎么回事字符。
如果有人有一些线索,那将不胜感激。
干杯
编辑:python 2.7
我刚刚在 Python 3.6.6 上尝试了您的测试,它按预期工作。我所做的唯一不同的事情是使用 re.compile
代替。看:
Python 3.6.6 (default, Jul 19 2018, 14:25:17)
[GCC 8.1.1 20180712 (Red Hat 8.1.1-5)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import re
>>> zipcode = re.compile(r'.*([0-90-9]{3}[-ー]{1}[0-90-9]{4}).*')
>>> zipcode.match("this is obviously not going to work")
>>> zipcode.match("this is going to work 123-4567")
<_sre.SRE_Match object; span=(0, 30), match='this is going to work 123-4567'>
>>> zipcode.match("this is going to work 123-4567").group(0)
'this is going to work 123-4567'
>>> zipcode.match("this is going to work 123-4567").group(1)
'123-4567'
>>> zipcode.match("this is going to work too 123ー4567").group(1)
'123ー4567'
>>> zipcode.match("This should not work, but it does : 1234ー567").group(1)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'NoneType' object has no attribute 'group'
>>> zipcode.match("This should not work, but it does : 1234ー567")
>>> zipcode.match("Now just seems crazy ....... 京都府")
>>> zipcode.match("京都府")
>>>
编辑
这是我目前的情况:
$ cat ziptest.py
# -*- coding: utf-8 -*-
import re
zipcode = re.compile(r'.*([0-90123456789]{3}[-ー]{1}[0-90123456789]{4}).*')
tests = (
"this is obviously not going to work",
"this is going to work 123-4567",
"this is going to work too 123ー4567",
"This will not work, as it should not : 1234-567",
"This should not work, but it does : 1234ー567",
"Now just seems crazy ....... 京都府",
"京都府",
"\xe4\xba\xac\xe9\x83\xbd\xe5\xba\x9c"
)
for test in tests:
print('%s: %s' % (test, "Match" if zipcode.match(test) else "No match"))
$
结果如下:
$ python2.7 ziptest.py
this is obviously not going to work: No match
this is going to work 123-4567: Match
this is going to work too 123ー4567: Match
This will not work, as it should not : 1234-567: No match
This should not work, but it does : 1234ー567: Match
Now just seems crazy ....... 京都府: No match
京都府: No match
京都府: No match
$ python3.6 ziptest.py
this is obviously not going to work: No match
this is going to work 123-4567: Match
this is going to work too 123ー4567: Match
This will not work, as it should not : 1234-567: No match
This should not work, but it does : 1234ー567: No match
Now just seems crazy ....... 京都府: No match
京都府: No match
京é½åº: No match
希望对您有所帮助。
regstr = ".*([0-90-9]{3}[-ー]{1}[0-90-9]{4}).*"
在 Python 3 中,regstr
将是一个包含一些非 ascii 字符的 unicode 字符串。在Python2中,它是一个以某种编码编码的字符串,这取决于你在模块开头声明的内容(参见PEP 263)和实际用于保存文件的编码。为避免此类问题,我建议您永远不要在正则表达式中使用 unicode 字符。那太难调试了。转而逃避他们。
0123456789是unicode字符'\uff10'
到'\uff19'
,所以我建议你这样使用。
此外,如果您使用的是 unicode 正则表达式,您应该这样定义它,使用 unicode strings 的 u
前缀:
regstr = u".*([0-9\uff10-\uff19]{3}[-\u30fc]{1}[0-9\uff10-\uff19]{4}).*"
稍后,当您将此正则表达式与某个字符串匹配时,其他字符串也应该是 unicode
字符串,而不是普通的 str
。为此,您必须知道输入的编码方式。例如,如果输入是 utf-8
,则使用:
input_string_as_unicode = unicode(input_string_as_utf8, 'utf-8')
re.match(regstr, input_string_as_unicode)
请注意,您可能已经有了 unicode
的输入,前提是背后有一些框架可以为您完成此操作。如果您不确定,请勾选 type(input_string)
。
我正在检查表格,是否输入了符合日文格式的邮政编码。 我今天意识到有些信息通过了,即使它不应该 "passed" 正则表达式匹配测试。
这是正则表达式:
".*([0-90-9]{3}[-ー]{1}[0-90-9]{4}).*"
包括普通数字和日文数字(“-”也一样,日文“ー”也可以输入),格式应该是这样的: 123-4567.
当只输入拉丁字母和数字时,它工作正常。 但是一些根本不匹配的日语字符......被return编辑为匹配:
(注意:匹配会 return 一些东西,不匹配将 return 什么都没有。)
>>> import re
>>> regstr = ".*([0-90-9]{3}[-ー]{1}[0-90-9]{4}).*"
>>> re.match( regstr, "this is obviously not going to work")
>>> re.match( regstr, "this is going to work 123-4567")
<_sre.SRE_Match object at 0x7fced8b485d0>
>>> re.match( regstr, "this is going to work too 123ー4567")
<_sre.SRE_Match object at 0x7fced8b48648>
>>> re.match( regstr, "This will not work, as it should not : 1234-567")
>>> re.match( regstr, "This should not work, but it does : 1234ー567")
<_sre.SRE_Match object at 0x7fced8b48648>
>>> re.match( regstr, "Now just seems crazy ....... 京都府")
<_sre.SRE_Match object at 0x7fced8b485d0>
>>> re.match( regstr, "京都府")
<_sre.SRE_Match object at 0x7fced8b48648>
>>> "京都府"
'\xe4\xba\xac\xe9\x83\xbd\xe5\xba\x9c'
>>> re.match( regstr, "\xe4\xba\xac\xe9\x83\xbd\xe5\xba\x9c")
<_sre.SRE_Match object at 0x7fced8b48648>
我尝试输入汉字,输入的两个字符不匹配。
所以居住在京都府的任何人...都可以 "bypass" 似乎是正则表达式,因为“京都府”足以使整个字符串有效。 这三个字符中只有两个不起作用。
我尝试了这三个字符的 unicode 代码,它也匹配(我想知道是否可以使用代码而不是字符本身来解析字符串,并想确保它没有'它包含实际上适合“000-0000”的内容。它没有,但它仍然匹配正则表达式)。
住在东京“东京府”的人会'less'幸运哈哈:
>>> re.match( regstr, "東京府")
>>> "東京府"
'\xe6\x9d\xb1\xe4\xba\xac\xe5\xba\x9c'
我在那里检查过:https://regex101.com/ 而那 3 个字符没有
所以...我在这里几乎迷路了。 使用更简单的“.([0-9]{3}[-]{1}[0-9]{4}).”作为正则表达式,它似乎是很好,但我真的不想限制用户只输入 [0-9-],因为很多人会输入日文版本 01234566789ー(更长)。 如果重要:
# 'Japanese numbers' code
>>> "0123456789ー"
'\xef\xbc\x90\xef\xbc\x91\xef\xbc\x92\xef\xbc\x93\xef\xbc\x94\xef\xbc\x95\xef\xbc\x96\xef\xbc\x97\xef\xbc\x98\xef\xbc\x99\xe3\x83\xbc'
我现在只是将日文0123456798ー转换为0123456789-,并应用一个完全不包含日文字符的正则表达式,但是......我真的很想知道正则表达式和日文是怎么回事字符。
如果有人有一些线索,那将不胜感激。
干杯
编辑:python 2.7
我刚刚在 Python 3.6.6 上尝试了您的测试,它按预期工作。我所做的唯一不同的事情是使用 re.compile
代替。看:
Python 3.6.6 (default, Jul 19 2018, 14:25:17)
[GCC 8.1.1 20180712 (Red Hat 8.1.1-5)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import re
>>> zipcode = re.compile(r'.*([0-90-9]{3}[-ー]{1}[0-90-9]{4}).*')
>>> zipcode.match("this is obviously not going to work")
>>> zipcode.match("this is going to work 123-4567")
<_sre.SRE_Match object; span=(0, 30), match='this is going to work 123-4567'>
>>> zipcode.match("this is going to work 123-4567").group(0)
'this is going to work 123-4567'
>>> zipcode.match("this is going to work 123-4567").group(1)
'123-4567'
>>> zipcode.match("this is going to work too 123ー4567").group(1)
'123ー4567'
>>> zipcode.match("This should not work, but it does : 1234ー567").group(1)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'NoneType' object has no attribute 'group'
>>> zipcode.match("This should not work, but it does : 1234ー567")
>>> zipcode.match("Now just seems crazy ....... 京都府")
>>> zipcode.match("京都府")
>>>
编辑
这是我目前的情况:
$ cat ziptest.py
# -*- coding: utf-8 -*-
import re
zipcode = re.compile(r'.*([0-90123456789]{3}[-ー]{1}[0-90123456789]{4}).*')
tests = (
"this is obviously not going to work",
"this is going to work 123-4567",
"this is going to work too 123ー4567",
"This will not work, as it should not : 1234-567",
"This should not work, but it does : 1234ー567",
"Now just seems crazy ....... 京都府",
"京都府",
"\xe4\xba\xac\xe9\x83\xbd\xe5\xba\x9c"
)
for test in tests:
print('%s: %s' % (test, "Match" if zipcode.match(test) else "No match"))
$
结果如下:
$ python2.7 ziptest.py
this is obviously not going to work: No match
this is going to work 123-4567: Match
this is going to work too 123ー4567: Match
This will not work, as it should not : 1234-567: No match
This should not work, but it does : 1234ー567: Match
Now just seems crazy ....... 京都府: No match
京都府: No match
京都府: No match
$ python3.6 ziptest.py
this is obviously not going to work: No match
this is going to work 123-4567: Match
this is going to work too 123ー4567: Match
This will not work, as it should not : 1234-567: No match
This should not work, but it does : 1234ー567: No match
Now just seems crazy ....... 京都府: No match
京都府: No match
京é½åº: No match
希望对您有所帮助。
regstr = ".*([0-90-9]{3}[-ー]{1}[0-90-9]{4}).*"
在 Python 3 中,regstr
将是一个包含一些非 ascii 字符的 unicode 字符串。在Python2中,它是一个以某种编码编码的字符串,这取决于你在模块开头声明的内容(参见PEP 263)和实际用于保存文件的编码。为避免此类问题,我建议您永远不要在正则表达式中使用 unicode 字符。那太难调试了。转而逃避他们。
0123456789是unicode字符'\uff10'
到'\uff19'
,所以我建议你这样使用。
此外,如果您使用的是 unicode 正则表达式,您应该这样定义它,使用 unicode strings 的 u
前缀:
regstr = u".*([0-9\uff10-\uff19]{3}[-\u30fc]{1}[0-9\uff10-\uff19]{4}).*"
稍后,当您将此正则表达式与某个字符串匹配时,其他字符串也应该是 unicode
字符串,而不是普通的 str
。为此,您必须知道输入的编码方式。例如,如果输入是 utf-8
,则使用:
input_string_as_unicode = unicode(input_string_as_utf8, 'utf-8')
re.match(regstr, input_string_as_unicode)
请注意,您可能已经有了 unicode
的输入,前提是背后有一些框架可以为您完成此操作。如果您不确定,请勾选 type(input_string)
。