Python Can';我不明白这个';url标签';正则表达式要准确

Python Can';我不明白这个';url标签';正则表达式要准确,python,regex,Python,Regex,我正在编写一个Python正则表达式来匹配URL。我写了一本相当复杂的书,效果相当不错。根据我在维基百科上读到的内容,我试图让主机名中的标签部分更加准确 基本上,如果您看到我的代码片段,我有一个真值表来测试我编写的标签部分。如果您想了解真值表,它基于主机名Wiki页面中的“主机名限制” 我无法在不破坏其他案例的情况下让案例1(字符串[0])正常工作,也无法找出案例1不起作用的原因。我曾使用过调试工具,但问题中的失败字符串太小,我无法获得任何重要信息 请帮助我,给我一个补丁,我写的,这样我就知道我

我正在编写一个Python正则表达式来匹配URL。我写了一本相当复杂的书,效果相当不错。根据我在维基百科上读到的内容,我试图让主机名中的标签部分更加准确

基本上,如果您看到我的代码片段,我有一个真值表来测试我编写的标签部分。如果您想了解真值表,它基于主机名Wiki页面中的“主机名限制”

我无法在不破坏其他案例的情况下让案例1(字符串[0])正常工作,也无法找出案例1不起作用的原因。我曾使用过调试工具,但问题中的失败字符串太小,我无法获得任何重要信息

请帮助我,给我一个补丁,我写的,这样我就知道我错过了什么

如果您想知道为什么我不使用第三方库来匹配URL,我正在学习正则表达式

import re

F = False
T = True

results = [T,F,T,F,F,F,T,F,T,F,F,F,F,F]

strings = ['a','-','aa','--','-a','a-','aaa','aa-','a-a','a--','-aa','-a-','--a','---']

x = list(range(len(strings)))

regex_test = r'(?P<Label>(?P<Label_start>[a-zA-Z0-9])((?P<Label_mid>[a-zA-Z0-9-]{1,61})?)(?=(?P<Label_end>[a-zA-Z0-9](?=[./])))(?P=Label_end)?)\.'

if len(strings) == len(results):
    for n in x:
        if results[n] == bool(re.match(pattern = regex_test, string = strings[n] + '.')):
            print("Works.")
            if results[n] == True:
                print(re.match(pattern = regex_test, string = strings[n] + '.').groupdict())
        else:
            print("Bug for: " + strings[n])
            #print(str(re.match(pattern = regex_test, string = strings[n] + '.',flags=re.DEBUG)))
重新导入
F=假
T=真
结果=[T,F,T,F,F,F,T,F,F,F,F,F,F,F]
字符串=['a'、'-'、'aa'、'-'、'-a'、'a-'、'aaa'、'aa-'、'a-a'、'a-'、'-aa'、'-a-'、'-a-'、'-']
x=列表(范围(长度(字符串)))
正则表达式测试=r'(?P(?P[a-zA-Z0-9])(?P[a-zA-Z0-9-]{1,61})(?=(?P[a-zA-Z0-9](?=[./]))(?P=标签末端)\。'
如果len(字符串)=len(结果):
对于x中的n:
如果结果[n]==bool(重新匹配(模式=regex_测试,字符串=strings[n]+')):
印刷品(“作品”)
如果结果[n]==真:
打印(重新匹配(pattern=regex_test,string=strings[n]+'.')).groupdict())
其他:
打印(“错误:“+strings[n]”)
#打印(str(re.match(pattern=regex_test,string=strings[n]+'.',flags=re.DEBUG)))
有时只使用python更容易(也更易读)!但是,域名验证的一部分得益于
re
。请看我的尝试,或下面我的完整狙击

# What are valid hostnames?
#    (1) Series of labels separated by periods.
#    (2) Each label can contain only letters, numbers and hyphens.
#    (3) Each label can not start or end with a hyphen.
#    (4) Each label can be 1-63 characters
#    (5) Entire domain cannot be longer than 253 characters.

import re

domains = ['en.wikipedia.org',
           'my.his-site.com',
           '-bad.site-.5345']

def is_valid_hostname(domain):
    # Utilize rule 1 to split into labels.
    labels = domain.split('.')

    for label in labels:
        # Check rules 2 and 3.
        if not re.search(r'^[A-z0-9][A-z0-9\-]*[A-z0-9]$', label):
           return False

        # Check rule 4.
        if not (0 < len(label) < 64):
            return False

    # Check rule 5.
    if len(domain) > 253:
        return False

    return True


for domain in domains:
    if is_valid_hostname(domain):
        print('{}:\tvalid'.format(domain))
    else:
        print('{}:\tinvalid'.format(domain))
什么是有效的主机名? #(1)以句号分隔的一系列标签。 #(2)每个标签只能包含字母、数字和连字符。 #(3)每个标签不能以连字符开头或结尾。 #(4)每个标签可以是1-63个字符 #(5)整个域不能超过253个字符。 进口稀土 域名=['en.wikipedia.org', “my.his site.com”, '-bad.site-.5345'] def是有效的主机名(域): #利用规则1拆分为标签。 labels=domain.split(“.”) 对于标签中的标签: #检查规则2和3。 如果没有重新搜索(r'^[A-z0-9][A-z0-9\-]*[A-z0-9]$,标签): 返回错误 #检查规则4。 如果不是(0253: 返回错误 返回真值 对于域中的域: 如果是有效的主机名(域): 打印(“{}:\tvalid.”格式(域)) 其他: 打印(“{}:\tinvalid.”格式(域))
这将是一个更大的正则表达式的一部分。我只需要将其作为正则表达式。此外,域名长度目前也不是一个考虑因素。但是谢谢你的超时和理解我的问题。那么你想要一个只有正则表达式的解决方案吗?在这种情况下,
^[0-9\p{L}][0-9\p{L}-\.]{1,61}[0-9\p{L}]\.[0-9\p{L}-][\p{L}-]*[0-9\p{L}]+$
将完成这项工作(请参阅副本)。我的正则表达式可能的副本几乎是准确的。请指出正则表达式无法匹配单个字符的原因。这将有助于我理解我的正则表达式哪里出错了。非常感谢。另外,我只需要标签而不是主机名方面的帮助。“.”被用作结束标志,因为这个正则表达式后面将跟主机名正则表达式的其余部分,然后是url正则表达式的其余部分。我会尝试在regex101.com之类的网站上使用您的正则表达式。还可以尝试简化语法(消除命名组)以尝试发现错误。你可以稍后再添加它们。我曾尝试在线调试它,但由于失败案例是一个非常小的字符串,甚至像Debuggex这样的工具也无法提供足够的信息。这个正则表达式([[:alnum:]{1,2})|([[[:alnum:][:alnum:]-]+a))$也通过了所有测试案例(请尝试)。它使用交替捕捉讨厌的1-2个字符大小写。