"Regular Expressions Must Know and Know (Revised Edition)" Reading Notes-Each Regular Expression Pro-test

 

// 正则表达式复杂准提:回溯引用(backreference)、条件性求值(conditional evaluation)和前后查找(lookingaround)
 /\b[Cc][Aa][Rr]\b/ //匹配car、CAR、CaR,但不匹配scar、carry、incarcerate
// 搜索:整个字符串搜索、自字符串搜索
// 正则表达式里的.字符相当于DOS的?字符,相当于SQL中的_(下划线)字符,.字符可以匹配任意单个的字符、字母数字甚至是.字符本身
/sales./.test("sales001");  // 正则表达式sales.将把有字符串sales和另外一个字符构成的字符串找出来
// 在.的前面加\字符转义表示需要的是.字符本身而不是它在正则表达式里的特殊含义
/.a.\.xls/.test("na1.xls"); // true
/.a.\.xls/.test("na11xls"); // false
// 在正则表达式里,\字符永远出现在一个有着特殊含义的字符序列的开头这个序列可以有一个或多个字符构成
// 在绝大多数的正则表达式实现里,.只能匹配除换行符以外的任何单个字符
// 用[和]来定义一个字符集合,字符集合的匹配结果是能够与该集合中的任意一个成员相匹配的文本
/[ns]a.\.xls/.test("nac.xls"); // true
/[ns]a.\.xls/.test("tac.xls"); // false
// 字符区间A-z匹配ASCII字符A到ASCII字符z的所有字母。这个模式一般不常用,因为它还包含着[和^等在ASCII字符表里排列在Z和a之间的字符
// -(连字符)是一个特殊的元字符,作为元字符它只能用字[和]之间。在字符集合以外的地方,-只是一个普通的字符,只能与-本身相匹配。因此,在正则表达式里,-字符不需要被转义。

// 用元字符^对一个字符集进行取非匹配,这与逻辑非运算很相似,只是这里的操作数是字符集合而已
/[ns]a[^0-9]/.test("sam.xls");  // true
/[ns]a[^0-9]/.test("sa1m.xls"); // false
// 定义一个元字符集合的做法:一是把所有的字符都列举出来;而是利用原字符-以字符区间的方式给出。
// 字符集合可以用字符^来求非;
/myArray\[0\]/.test("if(myArray[0]){"); //true 转义字符串对[和]分别进行转义
/myArray\[[0-9]\]/.test("if(myArray[6]){"); //true [0-9]元字符集匹配到数字
// \字符本身也是一个元字符,在需要匹配\本身时,必须把它转义为\\,在一个完整的正则表达式里,字符\后面永远跟着另一个字符
// JavaScript 1.x版本在String和RegEx对象的一下几个方法里表现了正则表达式处理:
// exec:一个用来搜索一个匹配的ReEx方法
// match:一个用来匹配一个字符串的String方法
// replace:一个用来完成替换操作的String方法
// search:一个用来测试在某给定字符串里是否存在着一个匹配的String方法
// split:一个用来把一个字符串拆分为多个子串的String方法
// test:一个用来测试在某给定字符串中是否存在着一个匹配的RegEx方法
// JavaScript命令行选项:s支持单行字符串,x忽略正则表达式模式的空白字符。
// JavaScript在使用回溯引用的时候,$'将返回被匹配字符串里面的所有东西,$`将返回被匹配字符串后面的所有东西,$+将返回最后一个被匹配的子表达式,$&将返回被匹配到的所有东西
// JavaScript不支持POSIX字符类
// JavaScript不支持\a和\z
// 空白元字符:[\b]回退(并删除)一个字符(Backspace键);\f换页键;\n换行键;\r回车键;\t制表符(Tab键);\v垂直制表符
// /\r\n/匹配一个"回车+换行"组合,有许多系统(比如Windows)都把这个组合用作文本行的结束标签。
// 使用正则表达式/\r\n\r\n/进行的搜索将匹配两个连续的行尾标签,而那正是两条记录之间的空白行。
// 元字符使用的差异:.和[是元字符,但前提是没有对它们进行转义,f和n也是元字符,前提是对他们进行了转义。如果没有对f和n进行转义,它们将被解释为普通字符,只能匹配它们本身。
// 匹配数字和非数字的类元字符:\d任何一个(单个)数字字符(等价于[0-9];\D任何一个非数字字符(等价于[^0-9])
/myArray\[\d\]/.test("if(myArray[6]){"); //true \d类元字符集匹配到数字
// 匹配字母数字和非字母数字的类元字符:\w任何一个字母数字字符(大小写均可)或下划线字符(等价于[a-zA-Z0-9_]);\W任何一个非字母数字或非下划线字符(等价于[^a-zA-Z0-9_])
// 匹配空白字符(与非空白字符):\s任何一个空白字符(等价于[\fn\r\t\v]);\S任何一个非空白字符(等价于[^\f\n\r\t\v]),用来匹配推个字符的[\b]元字符是一个特例:它不在类元字符\s的覆盖范围内,当然也就没有被排除在类元字符\S的覆盖范围外
// 有不少正则表达式实现还允许使用\c前缀来制定各种控制字符串。比如说,\cZ将匹配Ctrl-Z。\x0A表示十六进制,对应ASCII字符10(换行符),效果等价于\n。\011表示八进制,对应于ASCII字符9(制表符),其效果等价于\t。

Chapter 5 Repeated Matching

// +匹配一个或多个字符(至少一个,不匹配零个字符的情况)
// +是一个元字符,如果需要匹配+本身,就必须使用它的转义序列\+
// 在给一个字符集合加上+后缀的时候,必须把+放在这个字符集合的外面。比如说,[0-9]+是正确的,[0-9+]则不是。[0-9+]其实也是一个合法的正则表达式,但它匹配的不是一个或多个数字,它定义了一个由数字0到9和+构成的字符集合
// 一般来说,当在字符集合里使用的时候,像.和+这样的元字符将被解释为普通字符,不需要被转义,但转移了也没有坏处。[\w.]的使用效果与[\w\.]是一样的
// 只要把*字符放在一个字符(或一个字符集合)的后面,就可以匹配该字符(或字符集合)连续出现零次或多次的情况
// *可以没有匹配,+至少要匹配一次,?匹配零个或一个字符
/https?:\/\/[\w./]+/.test("https://www.forta.com/");  // true
/https?:\/\/[\w./]+/.test("http://www.forta.com/");  // true
// ?等价于{0, 1}
// 懒惰型元字符的写法很简单,只要给贪婪型元字符加上一个?后缀即可。贪婪型元字符:*、+、{n,};懒惰型元字符:*?、+?、{n,}?
/<[Bb]>.*?<\/[Bb]>/.test("This offer is not available to customers living in <B>AK</B> and <B>HI</B>.");  // true

Chapter 6 Location Matching

// \b指定单词边界,b是英文boundary(边界)的首写字母。\b用来匹配一个单词的开始或结尾
/\bcat\b/.test("The cat scattered his food all over the room"); // true
/\bcat\b/.test("The dog scattered his food all over the room"); // false
// \b匹配且只匹配一个位置,不匹配任何字符。用\bcat\b匹配到的字符串的长度是3个字符(c、a、t),不是5个字符
// \B表示不匹配一个单词的边界,即字母数字下划线之间,或者非字母数字下划线之间
// \B-\B将匹配一个前后都不是单词边界的连字符,nine-digit和pass-key中的连字符都不能与之匹配,但color - coded中的连字符可以与之匹配
// ^是几个有着多种用途的元字符之一,只有当它出现在一个字符集合里(被放在[和]之间)并紧跟在左方括号[的后面时,它才能发挥“求非”作用。如果是在一个字符集合的外面并位于一个模式的开头,^将匹配字符串的开头。
// 定义字符串边界的元字符有两个:一个是用来定义字符串开头的^,另一个是用来定义字符串结尾的$。
/^\s*<\?xml.*?\?/.test('<?xml version="1.0" encoding="UTF-8" ?><wsdl:');  // true
// ^匹配一个字符串的开头位置,所以^\s*将匹配一个字符串的开头位置和随后的零个或多个空白字符(这就解决了<?xml>标签前允许有空格、制表符、换行符等空白字符的问题)。.*?(解决贪婪型元字符问题的最佳办法是把.*替换为.*?),这里如果不用?限制可能会匹配上连续两个<?xml xxx ?>文件。
// 在一份Web页面里,</html>标签的后面不应该再有任何实际内容
/<\/[Hh][Tt][Mm][Ll]>\s*$/.test("<html><head></head> test</html>");  // true
// m表示启用分行匹配模式,因为*是一个贪婪型元字符,加上m之后,。*$将把换行符视为一个字符串分隔符,则这样就可以把每一行注释都匹配出来
/^\s*\/\/.*$/m.test(`function doSpellCHeck(form,field){
  // Make sure not empty
  if(FileReader.value==""){
    return false;
  }
  // Init
  ...
}`);  // true

Chapter 7 Using Subexpressions

// 子表达式必须用(和)括起来
// IP地址匹配,使用子表达式表示
/(\d{1,3}\.){3}\d{1,3}/.test("12.159.46.200");  // true
/(\d{1,3}\.){3}\d{1,3}/.test("123.1159.46.200");  // flalse
/(\d{1,3}\.){3}\d{1,3}/.test("1234.115.46.200");  // true 这算个bug,\b也许能解决
/\b(\d{1,3}\.){3}\d{1,3}/.test("1234.115.46.200");  // false 解决了
// 表示出生年份
/19|20\d{2}/.test("19why?");  // true,bug出在|后面的20\d{2}被当成一个整体了
/(19|20)\d{2}/.test("19why?");  // false, 用子表达式()包裹19|20,bug修复
// 把必须匹配的情况考虑周全并写出一个匹配结果符合预期的正则表达式很容易,但把不需要匹配的情况也考虑周全并确保他们都被排除在匹配结果以外往往要难得多!!!
// 周全的IP匹配
/(((\d{1,2})|(1\d{2})|(2[0-4]\d)|(25[0-5]))\.){3}(((\d{1,2})|(1\d{2})|(2[0-4]\d)|(25[0-5])))/.test("Pinging hog.rota.com [12.159.46.200] with 32 bytes of data"); // true 多次利用子表达式并嵌套
// 子表达式的常见用途:对重复次数元字符的作用对象做出精确的设定和控制、对|操作符的OR条件做出准确的定义等。
// 北美电话号码正则表达式:
/\(?[2-9]\d\d\)?[ -]?[2-9]\d\d-\d{4}/.test("J. Doe: 248-555-1234");
/\(?[2-9]\d\d\)?[ -]?[2-9]\d\d-\d{4}/.test("J. Smith: (313) 555-1234");
/\(?[2-9]\d\d\)?[ -]?[2-9]\d\d-\d{4}/.test("A. Lee: (810)555-1234");
// 北美电话号码的其他格式,如555.555.5555
/[\(.]?[2-9]\d\d[\).]?[ -]?[2-9]\d\d[-.]\d{4}/.test("J. Doe: 248-555-1234");
/[\(.]?[2-9]\d\d[\).]?[ -]?[2-9]\d\d[-.]\d{4}/.test("B. Smith: (313) 555-1234");
/[\(.]?[2-9]\d\d[\).]?[ -]?[2-9]\d\d[-.]\d{4}/.test("Lee: (810)555-1234");
/[\(.]?[2-9]\d\d[\).]?[ -]?[2-9]\d\d[-.]\d{4}/.test("M: Jones: 734.555.9999");
// 中国固定电话号码	最开始的位一定是0,表示长途,接着是两位、三位或者四位数字组成的区号,然后是7位或者8位的电话号码其中首位不为1(1用于特殊用途)
/\(?0[1-9]\d{1,3}\)?[-]?[2-9]\d{2,3}[-]?\d{4}/.test("029 8845 7890");
/\(?0[1-9]\d{1,3}\)?[-]?[2-9]\d{2,3}[-]?\d{4}/.test("(029) 88457890");
/\(?0[1-9]\d{1,3}\)?[-]?[2-9]\d{2,3}[-]?\d{4}/.test("029-8845 7890");
/\(?0[1-9]\d{1,3}\)?[-]?[2-9]\d{2,3}[-]?\d{4}/.test("029-8845-7890");
// 美国邮政编码
/\d{5}(-\d{4})?/.test("999 1st Avenue, Bigtown, NY,11222");
/\d{5}(-\d{4})?/.test("999 1st Avenue, Bigtown, NY,11222");
// HTML注释
/<!-{2,}.*?-{2,}>/.test("<!-- Start of Page -->");		// .*?这里用的是一个懒惰型元字符

 

Guess you like

Origin blog.csdn.net/taozi550185271/article/details/106599105