常用正则表达式和一些术语的译法


【图灵图书推荐】 正则表达式必知必会(即将出版)                             SQL 必知必会(第3版) 
                        +XML+HTML+CSS+JavaScript+UML=程序员真正的七种武器

【更新】经过仔细思考,初步确定译法如下。感谢lsf的贡献。

被几个正则方面的术语搞晕了,请方家告我。

backreference 回溯引用
其他译法:回溯(与backtrack的关系?)引用?后向引用?反向引用?

lookaround 前后查找
其他译法:环顾?环视?前瞻后顾?预测?全向预测?【lsf译法】定向查找

lookahead 向前查找
其他译法:前瞻?前预测?前向预测?预测先行?【lsf译法】向前查找

lookbehind 向后查找
其他译法:后顾?回顾?后预测?后向预测?回顾后发?【lsf译法】向后查找

positive/negative lookahead  正/负向前查找
负的意思其实是取非,但作为术语,不宜太长,而且相反的术语还是对称为好。
其他译法:正向,正序?【lsf译法】肯定式向前查找

常用正则

中国电话号码
先考虑普通座机的号码。不包括手机、一些特殊的号码,如119、800和其他业务型号码之类。这个网上有一些现成的答案(比如 这里的/d{3}-/d{8}|/d{4}-/d{7}),但是仔细学习《正则表达式必知必会》,感觉都不太对,只是一些workaround而已。Ben Forta在书中给出的北美号码正则是:
/(?[2-9]/d/d/)?[ -]?[2-9]/d/d-/d{4}
可以匹配248-555-1234,(248) 555-1234(括号后有空格)和(248) 555-1234(括号后无空格)形式的北美电话号码。人家是根据《北美编码方案》做的,应该比较bulletproof了。注意,北美编码,座机和手机是一视同仁的。

要写出一个比较好的中国电话号码的正则,必须从我国的电话号码规范着手。这就是《电信网编号计划》(2003年版)了。这里有一个比较正式的 规定号码资源的文件,但是有些地方看不大懂。这里有一个 对普通电话号码的介绍,比较全面了,而且能知道不少历史,比如为什么没有026这样的区号,023怎么给了重庆,像是预留的……

总结一下,规律是,最开始的位一定是0,这是死规定。然后可能是两位、三位或者四位区号。然后是7位或者8位电话号码(公网号码已经没有6位和以下的了),其中首位不为1(1用于特殊用途)。而国内习惯的电话格式有:029 8845 7890,029 88457890,(029)8845 7890,(029)88457890,029-8845 7890,029-88457890,029-8845-7890。对此,正则应该如下:
/(?0[1-9]/d{1,3}/)?[ -]?[2-9]/d{2,3}[ -]?/d{4}

大家看看对不对,还有没有更好的写法。

关于移动的编码,可以参考 这一篇文章
“目前移动网的号码由移动业务接入号+H0H1H2H3+ABCD组成,位长是11位。移动业务接入号有:中国联通GSM网是130、131、132,联通 CDMA网是133;中国移动GSM网是134、135、136、137、138、139;中国卫通全球星网是1349。H1H2H3为HLR识别号,确 认用户的归属地。ABCD为移动用户号。”

中国邮政编码
关于邮政编码的规律,目前只找到 这篇文章有点用,但是仍然语焉不详。
“我国邮政编码的编码规则:
我国采用四级六位编码制,前两位表示省、市、自治区,第三位代表邮区,第四位代表县、市,最后两位代表投递邮局,最后两位是代表从这个城市哪个投递区投递的,即投递区的位置。
例如:邮政编码“130021”“13”代表吉林省,“00”代表省会长春,“21”代表所在投递区。”

北京10,上海20,天津30,重庆40
内蒙古01,02,但也有13,16,73,75(和行政区划变化有关)
山西03,04
河北05,,06,07,有10,30的(和行政区划变化有关)
辽宁11,12
吉林13
黑龙江15,16
江苏21,22
安徽23,24
山东25,26,27
浙江31,32,但嵊泗 202450(看来原来属于上海)
江西33,34
福建35,36
湖南41,42
湖北43,44
河南45,46,47
广东51,52
广西53,54
贵州55,56
海南57
四川61,61,63,64
云南65,66,67
陕西71,72
甘肃73,74
宁夏75
青海81
新疆83,84
西藏85
香港999077
澳门999078
另外参见 这里(用带Tor的Firefox才能看,唉)。

总结一下,除港澳外,头一位0-8,第二位0-7,共6位。因此可以写出:
/d(9|[0-7])/d{4}

中国身份证号码
详细的可以参见 这里
(1)前1、2位数字表示:所在省份的代码;
(2)第3、4位数字表示:所在城市的代码;
(3)第5、6位数字表示:所在区县的代码;
(4)第7~14位数字表示:出生年、月、日;
(5)第15、16位数字表示:所在地的派出所的代码;
(6)第17位数字表示性别:奇数表示男性,偶数表示女性;
(7)第18位数字是校检码:也有的说是个人信息码,一般是随计算机的随机产生,
     用来检验身份证的正确性。校检码可以是0~9的数字,有时也用x表示。
这个列表可以总结出,第一位是1-8;出生年的前两位只能是18、19、20,而且可选(兼顾15位);月份中第一位只能是0或者1;日子的第一位只能是0-3;最后一位可选。因此可以写出这样的一个表达式:
[1-8]/d{5}((18)|(19)|(20))?/d{2}[0-1]/d[0-3]/d{4}[/dx]?



另外,发现微软中文文档有一段很搞笑的翻译:
原文:
Nonbacktracking Lookahead and Lookbehind 

Positive lookahead and lookbehind do not backtrack. That is, their contents are treated in the same way as the contents of a nonbacktracking (?> ) group.

Because lookahead and lookbehind are always zero-width, backtracking behavior is visible only when capturing groups appear within positive lookahead and lookbehind. For example, the expression (?=(a*))/1a will never find a match because group 1, which is defined within the lookahead, consumes as many "a" characters as there are, then /1a requires one more. Because the lookahead expression is not backtracked, the matching engine does not retry group 1 with fewer "a" characters.

For more on grouping, lookahead, and lookbehind constructs, see Grouping Constructs

中文:

非回溯预测先行和追溯

积极的预测先行和追溯不回溯。也就是说,对其内容的处理方式与对非回溯 (?> ) 组的内容的处理方式相同。

因为预测先行和追溯始终是零宽度的,所以仅当捕获组出现在积极的预测先行和追溯中时,回溯行为才是可见的。例如,表达式 (?=(a*))/1a 永远找不到匹配,因为在预测先行内定义的组 1 占用了所有的字符“a”,而 /1a 又请求一个“a”。因为预测先行表达式不是回溯的,所以匹配引擎不会重试具有较少的“a”的组 1。

有关分组、预测先行和追溯构造的更多信息,请参见分组构造


有谁认识微软MSDN中文负责同学的,请帮忙转告一下。

 


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值