55分钟学会正则表达式(来自Github)(6)

当你动态创建一个正则表达式的时候请特别小心。如果你使用的字符串不够完善的花,可能会有意想不到的匹配结果。这可能导致语法错误,更糟糕的是,你的正则表达式语法正确,但是结果无法预料。

错误的Java代码:

String sep = System.getProperty(“file.separator”); String[] directories = filePath.split(sep);

Bug:String.split() 认为sep是一个正则表达式。但是,在Windows中,Sep是表示匹配一个反斜杠,也就是与正则表达式”\\”相同。这个正则表达式是正确的,但是会返回一个异常:PatternSyntaxException.

任何好的编程语言都会提供一种良好的机制来跳过字符串中所有的元字符。在Java中,你可以这样实现:

String sep = System.getProperty(“file.separator”);

String[] directories = filePath.split(Pattern.quote(sep));

循环中的正则表达式

将正则表达式字符串加入反复运行的程序中,是一种开销很大的操作。如果你可以在循环中避免使用正则表达式,你可以大大提高效率。

其他建议 输入验证

正则表达式可以用来进行输入验证。但是严格的输入验证会使得用户体验较差。比如:

信用卡号

在一个网站上,我输入了我的卡号比如 1234 5678 8765 4321 网站拒绝接收。因为它使用了正则表达式\d{16}。

正则表达式应该考虑到用户输入的空格和短横线。

实际上,为什么不先过滤掉所有的非数字字符,然后再进行有效性验证呢?这样做,可以先使用\D以及空的替换表达式。

练习

在不先过滤掉所有的非数字字符的情况下,使用正则表达式验证卡号的正确性。

答案

\D*(\d\D*){16} is one of several variations which would accomplish this.

名字

不要使用正则表达式来验证姓名。实际上,即使可以,也不要企图验证姓名。

程序员对名字的错误看法:

名字中不含空格

名字中没有连接符号

名字中只会使用ASCII码字符

名字中出现的字都在特殊字符集中

名字至少要有M个字的长度

名字不会超过N个字的长度

人们只有一个名

人们只有一个中间名

人们只有一个姓(最后三条是从英语的人名考虑)

电子邮件地址

不要使用正则表达式验证邮箱地址的正确性。

首先,这样的验证很难是精确的。电子邮件地址是可以用正则表达式验证的,但是表达式会非常的长并且复杂。

短的正则表达式会导致错误。(你知道吗?电子邮箱地址中会有一些注释)

第二,即使一个电子邮件地址可以成功匹配正则表达式,也不代表这个邮箱实际存在。邮箱的唯一验证方法,是发送验证邮件。

注意

在严格的应用场景中,不要使用正则表达式来解析HTML或者XML。解析HTML或者XML:

使用简单的正则表达式不能完成

总体来说非常困难

已经有其他的方法解决

找到一个已经有的解析库来完成这个工作

这就是55分钟的全部内容

总结:

字符: a b c d 1 2 3 4 etc.

字符类: . [abc] [a-z] \d \w \s

. 代表任何字符

\d 表示“数字”

\w 表示”字母”, [0-9A-Za-z_]

\s 表示 “空格, 制表符,回车或换行符”

否定字符类: [^abc] \D \W \S

重复: {4} {3,16} {1,} ? * +

? 表示 “零次或一次”

* 表示 “大于零次”

+ 表示 “一次或一次以上”

如果不加上?,所有的重复都是最长匹配的(贪婪)

分组: (Septem|Octo|Novem|Decem)ber

词,行以及文本的分隔: \b ^ $ \A \z

转义字符: \1 \2 \3 etc. (在匹配表达式和替换表达式中都可用)

元字符: . \ [ ] { } ? * + | ( ) ^ $

在字符类中使用元字符: [ ] \ - ^

使用反斜杠可以忽略元字符: \

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wypdpg.html