re-learnning

xiaoxiao2021-03-01  20

001 regex 概述 ★正则表达式及其作用 老的: ? >> once * >> zero or more 正则表达式类似,强大了点,灵活了点 正则表达式[翻译的不好] regular expression 英文的意思是:符合某种规则的表达式 可以把正则表达式当一种语言[文本模式] 去匹配文本串,或者说文本串来匹配模式 正则表达式由一些元字符组成, 这些一组成,那么这个正则表达式就不是文本内容了, 而是一种文本模式 元字符(metacharacter)特殊字符 比如你要在一堆文字里查找这东西 要么5个数字 要么5个数字后加 连字符再加4个数字 共十个 可以用 \d{5}(-\d{4})? 正则表达式里的 ? 表示 once or not at all 重要重要 仅仅表示 紧考在 ? 前面 的元素项哦 所以我用()!! ----------------- 再说一个例子: 关于 ? 的 abc? 匹配 ab 或者 abc a(bc)? 匹配 a 或者 abc ----------------- 重要:刚刚看见() 的作用了 () 还有一个更厉害的作用: 他 括起来的东西也叫一个 "子匹配" 除了可以得到 整个 正则表达式的匹配结果外, 还可以单独得到每个 子匹配 所匹配的结果 就是说可以用() 把一个长的 正则表达式 分为多个子表达式 多个子表达式匹配的内容按照他们在正则表达式 左到右 出现 的顺序存储在缓存区里,这叫"捕获" 这样说肯定不懂,说个需求 我现在要匹配555香烟,三个数字要一样 \d{3}这样的话123 456 都出来了,不要!! --- 上面说完 捕获, 捕获好了后可以在整个表达式中位于 这个括号后的地方"反向引用" 第一个() 用 \1 表示 第二个() 用 \2 表示 ... 所以要匹配2个相同的连续数字字符的正则表达式为 (\d)\1 刚刚的三五香烟 (\d)\1{2} [就是说\1还得出来2次哦,必须2次哦] 要匹配这样的数字 1221 3553 7887 个位千位一样 十位百位一样 (\d)(\d)\2\1 ============= 来看看作用: 1 测试字串是不是匹配某个模式,看看输入的数据是不是有效 2 将一堆文本满足某一表达模式的文本内容替换或者删除[既替换为空即可] 比如在一堆文本中 把19XX的内容换成20XX [XX不变] 不可以简单的把19换20哦,否则1919 要变2020 ,而需求是1919变2019 如果是那么简单 word就可以解决问题了,呵呵 3 一堆里 搜索 某一类特征的文本内容 精确搜索:搜索一个具体的文本 .例如用 word 软件[必须提供精确内容哦] 而正则搜索: 可以搜索出某一类的文本[提供模式就可以了] -------- 顺便说一下为什么要用TXT CSV TXT存在是因为他太通用了,什么软件都可以打开查看 CSV是因为有时候TXT的一个整体里有空格什么的,很难分,所以用","了 -------- 说一个例子 在一文本里有上亿行数据[其中一行是这样的] 0.0.0.0 0.255.255.255 IANA 未知地区 现在要把这上亿条记录放DB里,三列,一二列是IP 第三列是说明 现在没有DB不认识,DB说我要根据什么分呢?空格?说明里也有空格啊 所以先要对数据处理 规则是 把前后有数字的空格变",",其他的空格不变! 只可以用 正则表示式了 我用的UltraEdit,他里面的替换要使用他自己的正则表达式 可以看看他的帮助,但是原理是一样的 我先找 "[0-9] +" [0-9是表示前面是个数,后面一个空格,+是一次或者多次] 把他替换为"," 但是这样有问题 ,连空格前的那个数字也替换了 我们要保留那个数字,怎么办?? 用子匹配捕获 "([0-9]) +" --要用UltraEdit自己定义的"^([0-9]^) +" 替换为 "^1," --这里是UltraEdit自己的反向引用 成功了!! 当然,UltraEdit非常强大,也提供通用的正则表达式 就是大家都在用的,正确的叫法是"Unix Syntax" 在UltraEdit,有 Regular Expressions (UltraEdit Syntax): Regular Expressions (Unix Syntax): 知道了吧 那么怎么在UltraEdit使用Unix Syntax呢?? 老版本里 高级|配置|查找|UNIX形式的正则表达式 新版本里,直接在查找 替换里选择 Regular Expressions Engine: 有三种: Perl Unix UltraEdit 慢慢玩吧 如果改了引擎,再按照上面的操作,什么都找不到了 要这样写了,这次不写引号了 ([0-9]) + \1, ===这个好,更通用了 再来一个例子: 也在UtralEdit里 有一个文件,N多行 "北京张肖像好老师","张肖像","zxx@itcast.com" "南极某老师好老师","笨蛋","bendan@ddd.com" 现在要发邮件了,N多个人都要发 一个一个复制邮件地址不可能 用正则表达式揪出来: (.+@.+\..+) 替换为 \1 .已经被定义是 元字符 所以要用真的. 要转义\. 上面的定义是不是有问题,是的 --- 顺便说一下,从一堆文本里找东西, 1把要的东西找出来 2把不要的东西删除 ---- 上面的意思是:把邮件地址找出来,替换为邮件地址, 根本就没有上面意义 要这样写:[不加引号了] .+"(.+@.+\..+)" \1 OK,查找的东西就匹配有邮件地址的一整行了, 然后只是把()里的邮件保留下来 看仔细,保留下来的只是邮件,两个引号也没有了,[不在()里] 这两个引号是邮件那一列的引号! 重要重要: 更加严格,更加规范的写法是: ^.+"(.+@.+\..+)"$ \1 ^表示行首,$表示行尾 写了这两个,那肯定是匹配一整行的 "北京张肖像好老师","张肖像","zxx@itcast.com" 如果不写,有可能只匹配: 好老师","张肖像","zxx@itcast.com" [如果好前面有什么特别的东西] 那么这样的话, 那个特殊的东西前面的东西就不被管辖了,仍然出现 还有一个问题: 如果我们不想发给163.net呢?怎么办?? wxjj@sina.com hubin@sott.com scott@oracle.net miller@jaone.net 334@163.net sie@163.net dfef@ssd.com 如果有这些,把163的弄掉 先用UtralEdit 引擎 --------- *@163.net [空白] ------------- 结果是 wxjj@sina.com hubin@sott.com scott@oracle.net miller@jaone.net dfef@ssd.com 我们不要空行,怎么办??? 重要:原来在每行后面,都有\r\n 也不要去弄清楚\r\n到底是写在行开头还尾巴处, 他们就是行和尾巴,在电脑里16个字符一行,任何符号都平等 \r\n的16禁止是: 0D 0A 现在知道了那么多,再弄弄好 不要空行出现了 规范的做法是 删此行的\n and 后面的\r 也可以说:删前一行的\n 和自己的\r 还有个\n留给上行的\r配对 --------UtralEdit 引擎---- ^n*@163.net^r [空白] ---------OK--- --------Unix 引擎---- .+@163.net [] ------------会出现空行 --------Unix 引擎---- ^.+@163.net$ [] ------------还是会出现空行 奇怪了[难怪UtralEdit强大] ^.+@163.net\p [弄好了,这样!前面可无^ 但是\p前不可以$] -------------- ==把所有域名换sina.ocm --------UtralEdit 引擎---- %^(*@^)*$ ^1sina.com ---------------可以,但是如果最后一行没有打回车,他不换 所以建议最行一行都按回车,为什么EDITPLUS 按键说明文本会多一行 如果用下面的会出现什么呢? --------UtralEdit 引擎---- %^(*@^)* ^1sina.com ----- wxjj@sina.comsina.com hubin@sina.comsott.com scott@sina.comoracle.net miller@sina.comjaone.net 334@sina.com163.net sie@sina.com163.net dfef@sina.comssd.com 现在知道为什么要设计$,否则都不知道哪里结束!就给了* --------Unix 引擎---- ^(.+@).+$ \1sina.com ----可以,试试不写$ ^(.+@).+ \1sina.com -----这个引擎不写倒是没有关系,但是推荐还是写为好 然后最后一个功能 把每行前都加# --------UtralEdit 引擎---- % # ---------OK ^r # --------在屁股后面加了 ^n # -------是在前面加了,不过加完都跑一行去了 还是用%把,反正文档也说%是开始 --------Unix 引擎---- ^ # -----非常简单 ★RegExp对象 ★String对象中与正则表达式有关的方法 ★语法参考 ★实用例子 ========================================== 001 regex 概述 ★正则表达式及其作用 ★RegExp对象 还是回到JS 在JS里有一个对象 RegExp 一条正则表达式模式对应一个RegExp对象 RegExp创建有两种方式 1显式构造函数 new RegExp("pattern"[,"flags"]) 2隐式构造函数 纯文本格式 /pattern/[flags] flag g : 全局标志 匹配一堆时,不设置这个标志,匹配完一次就结束了 [搜索一次,替换一次] 用了这了,匹配完整个一堆字串[搜索所有,替换所有] i : 忽略大小写标志 m : 多行标志 这个不设置,那么元字符"^" 只匹配一堆的第一个开始 "$"只匹配一堆的结束 如果设置了,"^"可以匹配\n 或者 \r [下行行首] "$"可以匹配\n或者\r 之前 [一行结束] 注意:\是特殊符号,所有在显式构造函数里,要\\ 等价的语句: var re = new RegExp("\\d{5}"); var re = /\d{5}/; 字符有 原义 和 转义 如果要表示 原义\ 在显式构造函数 四个 \\\\ 在隐式构造函数 两个 \\ -------- JS里,一个RegExp就全部包含了正则表达式 JAVA里,两个类包含了 Pattern Matcher C#里,不清楚了,看看MSDN了,好象非常多, regexp全世界都一样,会了一种语言的,另外的语言 只要稍微看看帮助就可以上手了 -------- RegExp对象的属性 1 静态属性 所有对象共享 2 实例属性 单个实例所有 1 静态属性 所有对象共享 静态属性一般是不变,但是也可以变 比如中国人这个类有个人口数量的变量 这个变量会随着每创建一个人而改变 2 实例属性 单个实例所有 静态属性 实例属性 index global input ignoreCase lastIndex multiline lastMatch source lastParen 实例方法 leftContext compile rightContext exec $1...$9 test 看MSDN,这里随便说一点 index 只读 当前的模式在一堆里面的第一次匹配的文本内容的位置[0开头] 初始值-1 匹配一次改变一次 lastIndex 只读 当前的模式在一堆里面的第一次匹配的文本内容的 最后一个字符的下一个位置.[0开头 就是0开始计数] 初始值-1 匹配一次改变一次 这个属性一般用来 作为一个起始位置,什么起始位置呢? 就是还用当前模式,匹配那一堆剩余的字串 input 初始值"" 返回模式现在在那个字串上作用的那个字串 lastMatch 初始值 "" 匹配一次改变一次 一个模式在一堆里可能多处匹配 这个返回最后一个匹配的字串 lastParen 初始值 "" 匹配一次改变一次 如果模式里有(),返回最后的()匹配的字串 leftContext 初始值 "" 匹配一次改变一次 模式在一堆里最后一个匹配的字串的 左边的所有字串 rightContext 初始值 "" 匹配一次改变一次 模式在一堆里最后一个匹配的字串的 右边的所有字串 $1...$9 模式里的(),模式可以写N 多() 但是JS只记得最后 9 个 但是在方法里,可以得到所有 global ignoreCase multiline 上面三个就flag里的三个字母 都是boolean值 source 模式的文本! 方法: test 格式: test(str), 重要: 只是检查这个str里是不是存在匹配我模式的字串, 是不是存在,存在了几次,呵呵, 现在明白为什么有^$了, 如果存在,那么就会改变 RegExp的那些静态变量了 对于这个方法,只要有存在的 就返回 true exec 格式: exec(str) 用我的模式去搜索str,返回搜索结果的数组 没有找到 null 找到了 数组,并也会更新 那些静态变量 找到的话,数组[0]是完整的匹配字符 1-N.. 是子匹配 这就是没有设置g 的match方法[设置了g的match方法的数组都是完全匹配的东西] 如果设置了g,从 lastIndex 搜 没有设置,整个都艘. 还有,返回的数组还用三个属性 input[一堆] index lastIndex[这两个都是描述匹配字串的] 可能会根据 lastIndex loop 再寻找吧[是的,看例子] compile 格式:compile("pattern"[,"flags"]); 更换模式,这个方法可以优化一下! 重要说明: 如果为模式设置了g, 如果设置了g,从 lastIndex 搜 多次调用exec test 方法 由于每次搜完后lastIndex都可能变,所以多次结果可能不同 统统找出来! 如果没有设置g 忽略lastIndex,每次都是从头开始 ★String对象中与正则表达式有关的方法 ★语法参考 ★实用例子 ======================================== 001 regex 概述 ★正则表达式及其作用 ★RegExp对象 弄个好例子吧,要不然白学了 找这样一个东西 a后一个数字b后二个数字c后三个数字 <html> <head> <script language="javascript"> var strSrc= "xxa1b01c001yya2b02c002zz"; var re = /a(\d)b(\d{2})c(\d{3})/gi; var arr ,count =0; while((arr=re.exec(strSrc))!=null) { displeyResult(); } function displeyResult() { document.write("<p>这是用正表达式/"+re.source+"/gi对字符串<br>\""+ RegExp.input+"\"进行第"+(++count)+"次查找的结果:<br>"); document.write("RegExp.index为"+RegExp.index+"<br>"); document.write("RegExp.lastIndex为"+RegExp.lastIndex+"<br>"); document.write("RegExp.lastMatch为"+RegExp.lastMatch+"<br>"); document.write("RegExp.lastParen为"+RegExp.lastParen+"<br>"); document.write("RegExp.leftContext为"+RegExp.leftContext+"<br>"); document.write("RegExp.rightContext为"+RegExp.rightContext+"<br>"); document.write("RegExp.$1为"+RegExp.$1+"<br>"); document.write("RegExp.$2为"+RegExp.$2+"<br>"); document.write("RegExp.$3为"+RegExp.$3+"<br>"); document.write("RegExp.$4为"+RegExp.$4+"<br>"); document.write("arr.inedex为"+arr.index+"<br>"); document.write("arr.input为"+arr.input+"<br>"); document.write("arr.lastIndex为"+arr.lastIndex+"<br>"); document.write("返回数组元素的个数为"+arr.length+"<br>"); document.write("返回数组元素的内容为["); for(var i=0;i<arr.length;i++) { if(i<arr.length-1) { document.write("\""+arr[i]+"\","); }else { document.write("\""+arr[i]+"\"]</p>"); } } } </script> <body> body! </body> </html> ★String对象中与正则表达式有关的方法 1 match 格式 match(re) [和exec方法交换了一下主宾关系] 如果在re里没有设置g,那返回的数组只有0完全匹配,其他子匹配 设置g, 数组里都是 完全匹配的 <html> <head> <script language="javascript"> var strSrc= "xxa1b01c001yya2b02c002zz"; var re = /a(\d)b(\d{2})c(\d{3})/gi; var arr = strSrc.match(re); document.write("返回数组元素的个数为"+arr.length+"<br>"); document.write("返回数组元素的内容为["); for(var i=0;i<arr.length;i++) { if(i<arr.length-1) { document.write("\""+arr[i]+"\","); }else { document.write("\""+arr[i]+"\"]</p>"); } } </script> <body> body! </body> </html> ------------ 返回数组元素的个数为2 返回数组元素的内容为["a1b01c001","a2b02c002"] ------------- 重要,不设置g 返回数组元素的个数为4 返回数组元素的内容为["a1b01c001","1","01","001"] 2 search方法 格式search(re) 返回第一个匹配的字串在一堆里的位置! 3 replace 格式replace(re,replaceTxt) 返回替换后的串或者一堆 先用re去找匹配的内容,再把找到的换掉 这里的re部分也可以是普通字串,那就要精确搜索了 replaceTxt这里也有考究了 $$ $原义 $& 整个模式匹配的内容 $` 位于$& 前面的内容 $' 位于$& 后面的内容 $n 第n个()里的内容 [非常有用] $nn 一样的,如果没有,就是输出$nn 一个例子 把a12b34c56这里的连续两个数字 调个个, a12b34c56 has been converted into a21b43c65 注意:这里的RE通常要设置g才可以替换所有的 4 split方法 格式:split(separator[,limit]) 返回一个数组 separator 可以是re或者多个字符 [不会作为数组的一部分返回] limit[要返回多少个,有时候不是要全部返回的] =====================回顾============ 重要: re的exec 有g 下一次从lastIndex 搜 while((arr=re.exec(strSrc))!=null) { displeyResult(); } 无g 老是从头开始 不管有g无g,回来的数组都只有第一个0完全匹配 str的match match(re) 如果在re里没有设置g,那返回的数组只有0完全匹配,其他子匹配 设置g, 数组里都是 完全匹配的 ================================= ★语法参考 ★实用例子 ===================== 001 regex 概述 ★正则表达式及其作用 ★RegExp对象 ★语法参考 要强大的使用RE,必须了解元字符 写RE,就是拼凑元字符 ★限定符[6个 3+3] 用来指定前面的 字符 或者 组合项 连续出现多少次. {n} : 前面的 字符 或者 组合项 必须要连续出现n次! o{2} 不匹配Bob里的o ,但是匹配food 也匹配boooook中的任意两个o {n,} : 前面的 字符 或者 组合项 至少要连续出现n次! o{2,} 不匹配Bob里的o ,匹配boooook中的 所有的o {n,m} : 前面的 字符 或者 组合项 连续出现[n,m] 两边都包含的 o{1,3} 匹配Bob里的o ,匹配book中的两个o 重要重要也匹配foooood里的连续三个o 其实刚刚的重要根本没有必要了,到了现在,应该理解了 对于电脑,一篇小说也是一串连续的东西,不要以为单词长了,太长了就不匹配了 那要匹配一本小说,有谁会把一个模式写成一本小说去匹配啊! + 等效 {1,} 必须出现一次或者多次 zo+ 匹配 zo zoo * 等效 {0,} zero or more ! zo* 匹配 z zoo ? {0,1} zo? 匹配 z zo 重要重要[都不知道该不该说 ] 也匹配 zoo 呵呵,匹配zoo里的zo部分,不匹配整个 zoo 上面有问题来了, o{1,3} 可以匹配1-3个o,那么到底匹配book中的几个o呢?? 贪兰匹配和非贪斓匹配 贪兰匹配[默认的] 要把zoom里的 zo? 换 r 结果是rom 不是room 要把zoom里的 zo* 换 r 结果是 rm 不是rom 也不是room 非贪斓匹配 把? 紧随任何其他 限定符(* + ? {n} {n,} {n,m} 匹配模式就变 非贪斓匹配 fooood里, fo+? 只匹配 fo 部分 [不贪] fo+ 就匹配了 foooo 了[贪了] ★选择匹配符[一个 |] 用来匹配 | 两边的任意一个 注意 | 两边的的表达式尽可能大哦 比如: chapter|section 1 只匹配 chapter 或者 section 1 不是 chapter 1 或者section 1 如果要匹配 chapter 1 或者section 1 可以这样写 (chapter|section) 1 ★分组组合和反向引用符 这两个是一对 ()分组组合 \n反向引用符,用来获得前面 捕获到的内容 (pattern) 捕获到的东西存在缓冲区,最多99个, 可以被反向引用,也可以在编程语言里检索到 如果要匹配 原义() 就要用 \( \) \n or \nn 这个最最强大,最最常用的功能,就是匹配 相同项目的能力 例如,要匹配连续5个字符 \d{5} 但是,要匹配连续5个 相同的 数字呢 就要用反向了 (\d)\1{4} =========找想同的单词出现========= <html> <head> <script language="javascript"> var strSrc = "Is is the cost of of gasonline going up up?"; var re = /\b([a-z]+) \1\b/gi; var arr = strSrc.match(re); document.write("返回数组元素的个数为"+arr.length+"<br>"); document.write("返回数组元素的内容为["); for(var i=0;i<arr.length;i++) { if(i<arr.length-1) { document.write("\""+arr[i]+"\","); }else { document.write("\""+arr[i]+"\"]</p>"); } } </script> <body> 返回数组元素的个数为3 返回数组元素的内容为["Is is","of of","up up"] </body> </html> =============================== (?:pattern) 有时候必须要用(),但是又不想存到缓存区就用这个好了 情况有: 不可以将 industry|industries 简单写成 industr(y|ise) 会影响 缓存区的位置的,你这个()里放的都是些没有实际意义的东西 就可以写成 industr(?:y|ise) (?=pattern)[这个不说情况打死也不知道再说什么] 正 向 预测先行 匹配 就是说 在 一堆里的东西附近一定要有这个,但是这个不放结果里, 更不放缓存里 比如在一大堆里有 window 2000 ,window NT ,window 2003 出现了N多次N多次,我现在只想对出现在2000 或者NT前的window操作怎么办? 就用这个 windows (?=NT|2000) 重要:匹配的结果 只是 windows 部分哦 如果把=变: 就匹配NT 或者 2000都进来了,虽然缓存里是不放的!! --------思考--- window (?=NT|2000) series ,会不会匹配 window NT series 这要想死人的,别想了 记得 这个东西要么写在最前,要么写在最后 --------------- (?!pattern)反 向 预测先行 匹配 说明在一堆的相应处,不可以出现模式里的东西 和上面的基本类似! window (?!NT|2000) 一大堆里有 window 2000 ,window NT ,window 2003 这下子只匹配 最后一个window ★特殊字符 RE里可以用(\)来表示 非打印字符 和 原义字符 \xn 匹配ASCII码等于n的字符n必须是两位16禁止数 \x41表示 A ,注意 \x041 表示 \x04 后面来一个1 这种方式一看就可以知道,可以匹配所有的字符,但是谁能记得呢??? \n 前面有() 当 反向引用 没有么 就只能0-7 ,ASCII码了 \nm 前面有() ,前小于n个, \n 当反向用 m普通字符 大于n个 nm一起上,当反响用 没有,都是一位的8禁止数, ASCII码了 \nml n小于3 最多(255)这些都是给高高手用的 ml8禁止数 ASCII码 \un unicode码了 n 四位16禁止数 \cx 匹配x 代表的控制字符 \cM 匹配 control + M 就是回车符了 x必须是字母,否则c就是c x就是x了 ----------- 重要:在ASCII码里 16禁止的 00 -1F 之间的数字所表现的字符 是不可见的,也打印不出来 这些字符叫 控制字符 他们在一些特殊的场合使用 每个控制字符都有一个英文名称来表示意义和作用 在一些终端上,就是用control + M 来表示回车的,它没有回车键 可以按. control + M 回车键 control + H 退各键 control + C 不知道什么键,反正有用 cmd里试吧 cmd里还有一个 control + i 看看吧 我们也可以用UtralEdit来看控制字符 view | views/list | ASCII table ----------- \t 匹配制表符 等效于 \x09 \cI \n 匹配换行符 等效于 \x0a \cJ \v 垂直制表符 等效于 \x0b \cK \f 匹配换页符 等效于 \x0c \cL \r 匹配回车符 等效于 \x0d \cM ★字符匹配符 1[] 匹配[]里多个字符的任意一个 如果模式里有 原义] ,必须放第一位,紧挨[后面,这样就认得, []里面的\仍然做 转义 要用原义 \\ 但是不知道 [ 原义怎么弄 2[^] 第一个是^ 就是排除,和上面对应的学 注意 ^不排第一 ,就是原义 3[a-z] 范围来了 注意:[]里要用 原义- 可\- [a\-z] [只有三个哦] 也可以把-放最前或者最后 [-a-z] [a-z-] [27个哦] 4[^a-z] 不在范围里的 \d 数字 等效 [0-9] \D 数字 等效 [^0-9] \s 等效[ \t\n\v\f\r] 任何空格 这里TMD是6个,有个空格看不见,呵呵 \S 等效[^ \t\n\v\f\r] \w 等效 [A-Za-z0-9_] 26+26+10+1 \W 等效 [^A-Za-z0-9_] . 匹配 所有的 除了 \n (.)\1 匹配除 \n 外的两个连续的相同的字符 [\s\S] [\d\D] [\w\W] 这三个什么字符都匹配了 如果要匹配 原义. 要\. 看一个例子, 结巴翻译 把下面的话理顺一下: "I...I...want...eat...eat...rice!" "我....我要...吃...吃肥肠面!" 变"我要吃肥肠面!" <html> <head> <script language="javascript"> var strSrc = "我....我要...吃...吃肥肠面!"; var strTgt= strSrc.replace(/\./g,"").replace(/(.)\1/g,"$1"); document.write(strTgt); </script> <body> body! </body> </html> ==============这个我自己弄了半夜======== <html> <head> <script language="javascript"> var strSrc = "I...I...want...eat...eat...rice!"; var strTgt= strSrc.replace(/(\.)+/g," ").replace(/(\w+) \1/g,"$1"); //var strTgt= strSrc.replace(/\./g," ").replace(/e/g,"E"); document.write(strTgt); </script> <body> </body> </html> ==========I want eat rice!====================== ★定位符 用于规定符合模式的字串出现的位置 这对验证非常有用 ^ 匹配字串的开始位置 注意^必须写在模式的最前才有这个用 例子: ^o与ok 里的o匹配 hello里的o不匹配! 如果设置了multiline属性[这个还是要好好推敲,一般输入验证,也就那么一段] ^还会与行首匹配 \n \r之后的位置匹配 $ 匹配字串的结尾位置 注意$必须写在模式的最后才有这个用 如果设置了multiline属性 \n \r之前的位置匹配 \b 两边不全是\w \B 非边界,应该好理解的 例子: er\B 匹配 verb 的er 不匹配never 的 er 定位符实用例子 ============================= 在对大段大段的文本操作的时候, 写模式要小心, 如果要匹配某一个单词 一定要/\bwin\b/g 边界一定要,英文单词单词里有单词很常见 ------------- 再来一个例子,搜索义每而 可以这样 /[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+/ 这可以搜索 邮箱地址了,但是搜不到我的,先不管 要注意的是这种不可以用的网页表单里 因为像这样 @.it33@it222.com.? 的不合法字串里包含有 合法的字串 用re.test()去验证,test不会关心合法字串出现的位置 所以,定位符还是要派上用场的 规范的写法/^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$/ 重要重要,但是你要在一堆里搜索,又不可以这样写了 哎,真够烦! -----------------再来一个定位符例子 要在每行前加一个# ,注释每行,可以这样: <html> <head> <script language="javascript"> var strTxt = "first line\n" + "second line\n" + "third line\n" + "fourth line\n" + "fifth line\n"; //document.write(strTxt.replace(/^/mg,"#")); alert(strTxt.replace(/^/mg,"#")); </script> <body> </body> </html> 一定要加 flag m g! ============================= ★原义字符 一些字符已经定义为 元字符 了,如果要用他们的原义 必须用 \ 来转义 需要转义的字符有: $ ( ) * + . [ ] ? \ / ^ { } | 对于/,由于写模式时需要用到它 所以要用/的原义,也必须转义 \/ ========== 看一下优先级别 ()最高 (ab)* ab组合后再和*组合 * ab* b和*先组合后再和a组合 字符 没有什么例子 | 最低 a|bc bc组合后,再和a组合 ========== ★实用例子 匹配空行[所有的空行(真空行,假空行都匹配)都匹配] /^\s*$/ 匹配假空行[就是说,直接换行的真空行不算,空行里有 空格,制表符等的空行] ^[\\s&&[^\\r]&&[^\\n]]\\s*\\n$ [查找脏空行的] 这个里有怎么使用 && 的. 就是说,开始是一个空白,但是这个空白不可以是直接就换行 匹配HTML标记 /<(\S+)(\s[^>]*)?>[\s\S]*<\/\1s*>/ 匹配email /[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+/ 匹配相同的相邻的单词[小写情况] /\b([a-z]+) \1\b/ 匹配IP /^\d{1,2}|1\d\d|2[0-4]\d|25[0-5](\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])){3}$/ =========== 重要重要,程序做判断 返回true一定要放最后,把不合法的都放前面,一有不合法的,直接return掉! 实用程序举例一 校验ip地址是否合法程序 第一种: function js_verify(addr) { var part_addr=addr.split("."); if(part_addr.length!=4) { return false; } else { var part; for(part in part_addr) { if(isNumeric(part_addr[part])) { if(parseInt(part_addr[part])<0||parseInt(part_addr[part])>255) { return false; } } else { return false; } } } return true; } function isNumeric(str) { if(str.length==0) { return false; } for(var i=0;i<str.length;i++) { if(str.charAt(i)<"0"||str.charAt(i)>"9") { return false; } } return true; } 第二种方法: function jsreg_verify(addr) { var reg=/^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/; if(reg.exec(addr)!=null) { //下面直接用字符串与数值比较,字符串将先转换成数值 if(RegExp.$1<0||RegExp.$1>255) return false; if(RegExp.$2<0||RegExp.$2>255) return false; if(RegExp.$3<0||RegExp.$3>255) return false; if(RegExp.$4<0||RegExp.$4>255) return false; } else { return false; } return true; } 第三种方法: /*reg_verify - 完全正则表达式来判断一个字符串是否是合法的ip地址,如果是则返回true,否则返回false.*/ function reg_verify(addr) { var reg=/^(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])(\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])){3}$/; if(addr.match(reg)) { return true; } else { return false; } } 用于检验的HTML代码: <p>输入要检验的ip地址:<input type=text name=txtIp value="255.222.33.111"><br> <input type=button name=btn1 value="测试JavaScript验证" οnclick="alert(js_verify(txtIp.value))"><br> <input type=button name=btn1 value="测试JavaScript和正则表达式验证" οnclick="alert(jsreg_verify(txtIp.value))"><br> <input type=button name=btn1 value="测试正则表达式验证" οnclick="alert(reg_verify(txtIp.value))"><br></p> ============copy it into IE===== <html> <head> <title>ss</title> <head> <script language="javascript"> function js_verify(addr) { var part_addr=addr.split("."); if(part_addr.length!=4) { return false; } else { var part; for(part in part_addr) { if(isNumeric(part_addr[part])) { if(parseInt(part_addr[part])<0||parseInt(part_addr[part])>255) { return false; } } else { return false; } } } return true; } function isNumeric(str) { if(str.length==0) { return false; } for(var i=0;i<str.length;i++) { if(str.charAt(i)<"0"||str.charAt(i)>"9") { return false; } } return true; } function jsreg_verify(addr) { var reg=/^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/; if(reg.exec(addr)!=null) { //下面直接用字符串与数值比较,字符串将先转换成数值 if(RegExp.$1<0||RegExp.$1>255) return false; if(RegExp.$2<0||RegExp.$2>255) return false; if(RegExp.$3<0||RegExp.$3>255) return false; if(RegExp.$4<0||RegExp.$4>255) return false; } else { return false; } return true; } function reg_verify(addr) { var reg=/^(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])(\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])){3}$/; if(addr.match(reg)) { return true; } else { return false; } } </script> </head> <body> 用于检验的HTML代码: <p>输入要检验的ip地址:<input type=text name=txtIp value="255.222.33.111"><br> <input type=button name=btn1 value="测试JavaScript验证" οnclick="alert(js_verify(txtIp.value))"><br> <input type=button name=btn1 value="测试JavaScript和正则表达式验证" οnclick="alert(jsreg_verify(txtIp.value))"><br> <input type=button name=btn1 value="测试正则表达式验证" οnclick="alert(reg_verify(txtIp.value))"><br></p> </body> </html> ======================over 实用程序举例二 ---从统一资源定位符(URL)中提取各组件信息 问题分析: 当浏览器地址栏中输入http://www.it315.org/book/welcome.html或http://192.168.0.1:8080/index.html等URL地址时,浏览器内部将会作出怎样的具体处理呢? 示例程序代码: <script> var reg=/(\w+):\/\/([^/:]+)(?::(\d*))?([^# ]*)/; var arr1="http://www.it315.org:8080/index.html".match(reg); var arr2="http://www.it315.org/book/welcome.html#mark1".match(reg); var str="协议,主机名,端口号,资源路径\n"; str+=arr1[1]+", "+arr1[2]+", "+arr1[3]+", "+arr1[4]+"\n"; str+=RegExp.$1+", "+RegExp.$2+", "+RegExp.$3+", "+RegExp.$4+"\n"; alert(str); </script> 实用程序举例三 ---创建能对多种常用格式进行验证的函数 <script> var patterns=new Object(); patterns.ip=/^(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])(\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])){3}$/; patterns.email=/^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$/; patterns.date=/^\d{4}-(0?[1-9]|1[0-2])-(0?[1-9]|[1-2]\d|3[0-1])$/;//匹配日期格式2008-01-31,但不匹配2008-13-00 patterns.time=new RegExp("^([0-1]\\d|2[0-3]):[0-5]\\d:[0-5]\\d$");//匹配时间格式00:15:39,但不匹配24:60:00 function verify(str,pat) { thePat=patterns[pat]; if(thePat.test(str)) { return true; } else { return false; } } alert(verify("00:00:11","time")+","+verify("it315@it315.org","email")+","+verify("192.168.1.1","ip")+","+verify("2003-00-31","date")); </script> ===================================
转载请注明原文地址: https://www.6miu.com/read-3200320.html

最新回复(0)