2010-08-30 74 views
2

我想知道如果这是一个好主意,避免正则表达式。避免正则表达式[python]

其实我避免它在任何情况下,有些人民一直给我意见,我不应该回避它,因为如果你知道是什么意思好像每一件事情:

[]“| “ \ A \ B \ d \ D \ W \ w \ S \ Z $ *? ...

它会很容易阅读,对吗?但我倒像避免正则表达式我会有一个更可读的代码。

它变得更加无法读取时,它的更大,例如:validators.py

email_re = re.compile(
    r"(^[-!#$%&'*+/=?^_`{}|~0-9A-Z]+(\.[-!#$%&'*+/=?^_`{}|~0-9A-Z]+)*" # dot-atom 
    r'|^"([\001-\010\013\014\016-\037!#-\[\]-\177]|\\[\001-011\013\014\016-\177])*"' #  quoted-string 
    r')@(?:[A-Z0-9](?:[A-Z0-9-]{0,61}[A-Z0-9])?\.)+[A-Z]{2,6}\.?$', re.IGNORECASE) # domain 

所以,我想知道一个理由,不能避免正则表达式?

+0

一封电子邮件。如果我的正则表达式阅读技能仍然达到标准,那就很糟糕。 – muhmuhten 2010-08-30 02:00:44

+0

@sreservoir如在一个电子邮件地址? – NullUserException 2010-08-30 02:01:27

+6

我想避免编码。我一直在避免它,但人们总是告诉我,我不应该避免它。但如你所知,这意味着使用大括号和怪异的资本化,这使得阅读变得更加困难。 – 2010-08-30 02:01:45

回答

18

不,不要避免使用正则表达式。他们实际上是一个非常漂亮的小工具,如果你明智地使用它们,会为你节省很多工作。

做什么需要避免试图使用它的一切,这似乎打击那些新的正则表达式,他们变得有点钢化玻璃和少一点迷恋:-)

之前萎靡不振例如,不要用它来验证电子邮件地址。您验证电子邮件地址的方式是通过链接发送电子邮件给收件人,该链接必须点击以完成“交易”。

有数十亿有效的电子邮件地址(根据RFC)没有物理电子邮件接收器。 只有方式确定有一个接收器是发送一封电子邮件,并等待证据证实它已被接收并采取行动。

如果我发现自己编写的正则表达式不止60个字符,我会回过头来看看是否有更可读的方式。同样,如果我写一个正则表达式并在一周后回来,并且无法立即识别它的作用,我想要替换它。这种特殊的段落是由我当然意见,但他们已经使我受益匪浅:-)

+4

我同意发送一封电子邮件来确认地址的存在是好的,但很高兴检查输入的电子邮件地址是否无效。用户可能会忘记'@',你可以检查它是否在那里并给出错误。做到这一点比接受它更好,并通过电子邮件发送失败。用户不知道他为什么没有收到他的电子邮件。 – avacariu 2010-08-30 02:34:24

+4

@ vlad003 - 那么你只需使用'if'@“in email_address ...' - 在这种情况下,正则表达式是过度杀伤。任何比这更复杂的事情,你要求麻烦... – detly 2010-08-30 03:30:08

+0

@vlad,检查一个“@”和你必须使用一个完全验证的电子邮件地址的怪物之间有很大的区别。通过一切手段做一个这样的简单检查,它至少是可读的:-) – paxdiablo 2010-08-30 03:32:33

2

如果您选择使用一个更一般的分析方法,像pyparsingPLY,你将永远不会需要正则表达式(其只能匹配与这些一般解析器匹配的语言的一小部分)。然而,诸如PLY这样的词法分析器通常是围绕正则表达式构建的(这与词法分析器的需求完美匹配!),因此您可能必须避免这种情况(以及功能强大的工具,例如BeautifulSoup,当任何“正常”用户只需传递一个正则表达式对象作为选择器就可以继续使用和享受它,因为BeautifulSoup完全支持这一点),并且必须用您选择的通用解析包重新编码许多这样的现有解析器。

当然,如果更简单,高度优化和简洁的应用程序是一个完美的解决方案,那么性能可能会受到很大的影响,而且代码的大小可能会“爆炸”,变得非常大很多常见的情况。但是,如果你不介意让程序两倍大,两倍慢,并决心不惜一切代价避免正则表达式,你可以可以做到这一点。另一方面,如果你主要关心的是可读性(也是一个可以理解和值得关注的问题),那么re.VERBOSE选项通过在RE模式中充分使用空格和注释,可以真正实现奇迹该目标没有删除RE的优势(除了稀释一个有时过分的简洁;-))的任何。你会想保持至少一个通用分析系统,在你的腰带,当然(而不是拉伸的RE做他们是错的任务,所以很多人不幸呢!) - 但最小的命令的REs会在很多情况下为您提供良好的服务(包括例如充分利用BeautifulSoup以及其他许多可以接受RE作为参数的工具),我认为这是相当值得推荐的。

6

正则表达式是一种工具。它们完全适合于某些任务,而不适用于其他任务。像任何工具一样,在他们是工作的正确工具时使用它们。不要只因为有人说他们不好就避免他们。学习如何使用它们,然后你可以自己决定,而不是依赖别人的教条。

-1

正则表达式是可能用于提取/验证电子邮件地址正确的工具...

从原始文本中提取一个或多个电子邮件地址:

import re 
pat_e = re.compile(r'(?P<email>[\w.+-][email protected](?:[\w-]+\.)+[a-zA-Z]{2,})') 
emails = [] 
for r in pat_e.finditer(text): 
    emails.append(r.group('email')) 
return emails 

要查看是否有单件的文本是一个有效的电子邮件:

import re 
pat_m = re.compile(r'([\w.+-][email protected](?:[\w-]+\.)+[a-zA-Z]{2,}$)') 
if pat_m.match(text): 
    return True 
return False 
+1

对于某个电子邮件地址的'@',它是[完全有效](http://en.wikipedia.org/wiki/Email_address#Specification)之前的加号('+'),这会失败。 – detly 2010-08-30 03:35:57

+2

当他们决定创建一个5个字母的TLD时会发生什么? – Gabe 2010-08-30 03:54:59

+1

曾听说过.museum和.travel顶级域名? – Schnouki 2010-08-30 11:52:08

1

只是一些comparisions,在这里我的版本的电子邮件格式检查不与正则表达式(测试用例)和一个可读的正则表达式提供给我作为替代(虽然它被接受后,发送电子邮件,是伟大的想法):

# -*- coding: utf8 -*- 
import string 
print("Valid letters in this computer are: "+string.letters) 
import re 
def validateEmail(a): 
    sep=[x for x in a if not (x.isalpha() or 
           x.isdigit() or 
           x in r"!#$%&'*+-/=?^_`{|}~]") ] 
    sepjoined=''.join(sep) 
    ## sep joined must be [email protected] form 
    if len(a)>255 or sepjoined.strip('.') != '@': return False 
    end=a 
    for i in sep: 
     part,i,end=end.partition(i) 
     if len(part)<2: return False 
    return len(end)>1 

def emailval(address): 
    pattern = "[\.\w]{2,}[@]\w+[.]\w+" 
    return re.match(pattern, address) 

if __name__ == '__main__': 
    emails = [ "[email protected]","[email protected]", "[email protected]", 
       "[email protected]", "[email protected]","marjaliisa.hämälä[email protected]", 
       "marja-liisa.hämälä[email protected]", "[email protected]",'[email protected]', 
       '[email protected]','[email protected]'] 

    print('\n\t'.join(["Valid emails are:"] + 
         filter(validateEmail,emails))) 

    print('\n\t'.join(["Regexp gives wrong answer:"] + 
         filter(emailval,emails))) 

""" Output: 
Valid letters in this computer are: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ 
Valid emails are: 
     [email protected] 
     [email protected] 
     [email protected] 
     [email protected] 
     [email protected] 
Regexp gives wrong answer: 
     [email protected] 
     [email protected] 
     [email protected] 
""" 

编辑:从这个古老的代码清理正则表达式过滤功能,编辑的@detly基于链路更加宽容的版本。在发送确认电子邮件之前,我已经足够填写表格了。 Finaly在评论中提到了255字符长度限制检查。

此代码按用途不接受正常的一个@ B中有效的电子邮件地址,但不会接受我@地方。另一件事是它取决于isalpha返回。所以这个来自Ideone.com的输出结果并不接受斯堪的纳维亚öä,即使它们现在也是有效的。在我的家用电脑上运行时,这些被接受。即使编码线在那里。

0

(删除的正则表达式,自称是一个“官”之一,但其实是在它声称是从RFC没有找到。)

This正则表达式可能是有趣的,因为它是试图精确匹配旧版互联网邮件标准中提供的电子邮件地址语法。

+0

把“官方”放在引号内是一个死的东西,它是什么,但官方:-) – paxdiablo 2010-08-30 05:14:16

+0

我去寻找“官方”是如何,发现你是对的。因此,我将一个链接换成了一个更加流畅的正则表达式,声称它能够满足大部分RFC 822标准。 :-) – kindall 2010-08-30 05:48:47

0

不用多说正则表达式是一个非常强大的工具,如果你有兴趣做网页抓取或基本上是包括大量的文字处理模式的任何其他任务,你必须学习正则表达式。

现在,阅读文档,是不是很有趣,所以我建议你使用this chrome plugin练习您正则表达式的技能。这是一种非常有趣的方式来测试一个正则表达式是否符合您的要求,并且可以帮助您更快地学习语言。

好练习:)