正则表达式返回true,带不正确的日语字符

2024-10-04 11:31:59 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在用表格检查是否输入了符合日本格式的邮政编码。 我今天意识到有些信息已经通过了,尽管它不应该“通过”regex匹配测试。你知道吗

这里是正则表达式:

".*([0-90-9]{3}[-ー]{1}[0-90-9]{4}).*"

它包括普通数字和日语数字(与“-”相同,也可以输入日语数字“ー”),格式如下: 123-4567. 你知道吗

当只输入拉丁字母和数字时,工作正常。 但有些日语字符根本不匹配。。。作为匹配项返回:

(注意:匹配将返回某些内容,没有匹配将不返回任何内容。)你知道吗

>>> 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>

我试着输入汉字,但我试过的两个汉字不匹配。你知道吗

所以住在京都县的人。。。似乎可以“绕过”正则表达式,因为“京都府”足以使整个字符串有效。 这三个角色中只有两个行不通。你知道吗

我试过使用这三个字符的unicode代码,但它也匹配(我想知道是否可以使用代码而不是字符本身来解析字符串,并希望确保它不包含真正适合“000-0000”的内容)。它没有,但它仍然匹配正则表达式)。你知道吗

住在东京的人“東京府”会“少”些幸运哈哈:

>>> re.match( regstr, "東京府")
>>> "東京府"
'\xe6\x9d\xb1\xe4\xba\xac\xe5\xba\x9c'

我查过:https://regex101.com/这3个字符没有

所以。。。我在这里迷路了。 更简单的“([0-9]{3}[-]{1}[0-9]{4})。“作为regexp,它看起来很好,但我真的不想限制用户只输入[0-9-],因为许多人将输入日语版本0123456789ー(更长)。 如果有关系:

# '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


Tags: reobjectmatchnot数字字符atwork
2条回答

我刚刚在python3.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}).*"

在python3中,regstr将是包含一些非ascii字符的unicode字符串。在python2中,它是以某种编码方式编码的字符串,这取决于您在模块开头声明的内容(请参见PEP 263)以及实际用于保存文件的编码。为了避免这样的问题,我建议您永远不要在regex中使用unicode字符。这太难调试了。而不是逃离他们。你知道吗

字符0123456789是unicode字符'\uff10''\uff19',所以我建议您应该这样使用它们。你知道吗

此外,如果您使用的是unicode正则表达式,那么应该使用unicode stringsu前缀来定义它:

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)。你知道吗

相关问题 更多 >