JavaScript 学習まとめ (7) JS RegExp

黄舟
黄舟オリジナル
2017-02-10 09:25:181375ブラウズ

jsでは、正規表現はRegExpオブジェクトで表されます。 RegExpは正規表現の略です。 RegExp の単純なパターンは 1 文字にすることができます。より複雑なパターンにはより多くの文字が含まれており、解析、形式チェック、置換などに使用できます。 RegExp() コンストラクターを使用して RegExp オブジェクトを作成することも、直接構文を使用することもできます

js では、正規表現は RegExp オブジェクトによって表され、RegExp は正規表現の略称です。 RegExp の単純なパターンは 1 文字にすることができます。より複雑なパターンにはより多くの文字が含まれており、解析、形式チェック、置換などに使用できます。 RegExp() コンストラクターを使用して RegExp オブジェクトを作成することも、リテラル構文を使用することもできます。

1. RegExp の概要。

RegExp は正規表現 (コードでは regex、regexp、または RE/re/reg と略されることが多い正規表現) で、単一の文字列を使用して、特定の構文ルールに準拠する一連の文字列検索パターンを記述し、一致させます。検索モードはテキスト検索とテキスト置換に使用できます。

正規表現は文字列で構成される検索パターンで、テキスト内のデータを検索するときに、その検索パターンを使用してクエリしたい内容を記述することができます。文字パターンを使用して、文字列のパターンを照合し、検索および置換することができます。

いわゆる正規表現は、コンピュータが理解できる一定の規則を表現するルールやパターン表現として直接理解できますが、一般の人には理解しにくい文字表現であり、あらゆる用途に使用できます。テキスト検索とテキスト置換操作、簡単に言えば、文字列を処理することです。

2. 文字列メソッド。

(1), charAt() 特定の文字を取得し、文字列内の特定の文字を返します。

(2)、split() 文字列を分割して配列を取得します。

(3), search() 特定の文字が最初に出現する位置を検索します。 見つからない場合は、戻り値が数値になります。

(4), match() 文字列内で指定された文字を検索し、その文字を返します。正規表現を使用しない場合は、指定された文字の最初の出現のみが返され、後方一致は実行されません。正規表現を使用してグローバル マッチングを実行すると、文字列内の指定されたすべての文字が配列として返され、見つからない場合は null が返されます。

(5), replace() 文字を置換し、新しい文字列を返します。正規表現と組み合わせて使用​​すると、すべての一致を置換できます。

 <script>
 var str=&#39;abcdefgca&#39;;
 //返回字符串中某一位的字符。
 alert(str.charAt());  //返回:d
 //查找字符串首次出现的位置。
 alert(str.search(&#39;z&#39;));  //返回:-
 //查找指定的字符。
 //只返回第一次出现的c,不再向后匹配。
 alert(str.match(&#39;c&#39;));  //返回:c
 //将&#39;a&#39;替换为&#39;i&#39;。
 //只替换了第一个位置的a,不再向后匹配。
 alert(str.replace(&#39;a&#39;, &#39;i&#39;));  //返回:ibcdefgca
 //分割字符串。
 var str=&#39;--aaa--cd&#39;;
 var arr=str.split(&#39;-&#39;);  //返回:,,aaa,,cd
 alert(arr);
 </script>

例: 通常のメソッドを使用して文字列内のすべての数値を検索します

実装のアイデア: 文字列内の数値を見つけるのは難しいことではありません。最初に文字列内の数値を抽出します。 out の場合、文字列には複数の数値が含まれている必要があるため、抽出された数値を格納するために空の文字列が必要になります。その後、これらの数値を配列に追加し、最後に戻って完了です。プログラムがどのように実装されるかを見てみましょう:

 <script>
 var str=&#39; abc d aa c zz -=-=s-&#39;;
 var arr=[];
 var num=&#39;&#39;;
 //首先循环遍历字符串
 for(var i=;i<str.length;i++){
   //再判断当前字符大于等于并且小于等于,则为数字
   if(str.charAt(i)>=&#39;&#39; && str.charAt(i)<=&#39;&#39;){
     //那么就将当前的字符存储在空字符串中
    num += str.charAt(i);
   }
   else{
     //如果字符串中有值。
     if(num){
       //将值添加到数组中。
       arr.push(num);
       //再清空字符串,避免重复添加。
       num=&#39;&#39;;
     }
   }
 }
 //最后在整个字符串结束之后有可能还会有数字,再做一次判断。
 if(num){
   //如果还有值就添加到数组中。
   arr.push(num);
   //再清空字符串。
   num=&#39;&#39;;
 }
 //返回:OK,现在返回就完成了。
 alert(arr); //返回:,,,,,,,
 </script>

これは通常のメソッドを使用して完了でき、明確な構造を持っていますが、正規表現を使用すると、コードは比較的長くなり、1 つの式で非常に多くの作業を完了できます。とても便利な正規表現の使い方を見てみましょう。

3. 通常のルールを使用します。

正規表現の構文: var re = new RegExp('pattern', 'modifier');

パターンは式のパターンであり、修飾子はグローバルマッチング、大文字と小文字の区別などを指定するために使用され、完全な形状になりますは正規表現です。

このように通常の構文を見ると、JSで新規に作成するオブジェクトの典型的な構文ではないでしょうか? ちなみに、通常のオブジェクトを新規に作成するという意味です。 new キーワードの使用は避けるべきであることは誰もが知っていますが、new を使用すると間違いなく新しいオブジェクトが作成され、適切に処理しないと過剰な蓄積によりメモリ オーバーフローが発生することになります。リソースが非常に高価であり、コードの最適化の実装には役立ちません。同時に、この書き方は規則性の力を反映していないため、実際の使用では、この JS スタイルの通常の構文は使用されず、次のような別のスタイルが使用されます。

構文: var re = /mode/modifier;

このスタイルは比較的簡潔で、ほとんどの人が理解できない表現です。

(1)、修飾語。

修飾子は、グローバルマッチングと大文字小文字の区別を実行するために使用されます。

大文字小文字を無視: i (ignore の略語、中国語訳:ignore)

グローバル一致: g (global の略語、中国語訳: all/global)

例: 指定された文字のグローバル検索

 <script>
 var str=&#39;AbCdEFgiX&#39;;
 //JS风格:
 //这个正则表达式什么也不代表,只代表abc本身。
 var reg=new RegExp(&#39;abc&#39;, &#39;i&#39;);
 alert(str.match(reg));  //返回:AbC
 //常用风格:
 var re=/efg/i;
 alert(str.match(re));  //返回:EFg
 </script>

4、角括弧とメタキャラクター。

(1) かっこ。

角括弧は、特定の範囲内の文字を検索するために使用されます。

①、任意の文字
式:[abc]
角括弧内の任意の文字を検索します。
ここでの[]は、つまり、どちらが出ても良いという意味です。

りー

   ②、范围查找。

  表达式:[0-9] [a-z] [A-z] [A-Z]

  [0-9]  查找任意 0 - 9 的数字。

  [a-z]  查找任意 a - z 的字符。

  [A-z]  查找任意 大写A - 小写z 的字符。

  [A-Z]  查找任意 大写A - 大写Z的字符。

  ③、排除查找。

  表达式:[^abc] [^a-z] [^0-9]

  [^abc]  查找任意不在方括号中的字符。

  [^a-z]  查找任意除了字母以外的字符,包括数字符号中文外文。

  [^0-9]  查找任意除了数字以外的字符,包括字母符号中文外文。

 <script>
 var str=&#39;ot out o.t o t o`t ot ot&#39;;
 //o和t中间除了数字,什么都可以
 var re=/o[^-]t/g;
 alert(str.match(re));  //返回:out,o.t,o t,o`t
 </script>

  ④、选择查找。

  表达式:(a|b|c)

  查找任何指定的选项,a或b或c。

  ⑤、匹配还可以使用组合模式,比如:[a-z0-9A-Z] [^a-z0-9]

  [a-z0-9A-Z]  任意大小写字母和数字。

  [^a-z0-9]  除了字母和数字以外,什么都可以。

  (2)、元字符。

  元字符是拥有特殊含义的字符,也可以叫做转义字符。

  下面是一些常用的元字符:


メタキャラクター 説明
. を使用して、改行と行終端記号を除く任意の文字を表す単一の文字を検索します。 問題が発生しやすいため、使用はお勧めしません。
w [a-z0-9] に相当する英語の数字とアンダースコアを含む単語文字を検索します /w/
W 非を見つける-words [^a-z0-9] /W/
d に相当する文字、[0-9] /d/に相当する数字を検索します
D [^0-9] に相当する非数字を検索します /D/
s スペースや車を含む空白文字を検索しますリアージュが戻る文字、タブ文字、改行文字、非印刷文字は表示できません。 /s/
S 空白以外の文字を検索します。 /S/
b 単語の先頭または末尾で一致を検索します。一致が見つからない場合は null を返します。 /b/
B

単語の境界にない、つまり先頭や末尾にない一致を検索し、一致する位置で前後の文字の型を検索します。位置は同じです: つまり、両方の単語である必要があります (

)、または非単語である必要があります () 文字列の先頭と末尾は非単語文字として扱われ、一致しない場合は null が返されます。

/B/
n 改行文字を検索し、見つかった場合はその位置を返し、見つからなかった場合は -1 を返します。 /n/
f 改ページを見つけます。 /f/
r 復帰文字を検索します。 /r/
t タブ文字を検索します。

5. 数量化子。

いわゆる量指定子は量指定子、つまり数値であり、出現回数を表すために正規表現で使用されます。

一般的に使用される量指定子を以下に示します:


*
数量子 は、
を使用して を説明します。{0,}に相当します 範囲が広すぎるため推奨しません、十分な精度ではありません。
? ゼロまたは 1 回、{0, 1} に相当 /10?/g 0' の直後のゼロまたは 1 を含む、1 のグローバル検索を実行します。
+ 1 回またはいつでも、{1, } /w+/g と同等 少なくとも 1 つの単語のグローバル検索を実行します。
{n} ちょうど n 回 /d{4}/g 4 桁を含む数値のグローバル検索を実行します。
{n,} 少なくとも n 回、制限なし /d{3,}/g 少なくとも 3 桁を含む数値のグローバル検索を実行します。
{n, m} 少なくともn回、最大m回 /d{3,4}/g 3桁または4桁を含む数値のグローバル検索を実行します。

以下は一般的に使用されるマッチング パターンの一部です:


/^d/ で始まります数字 / ^a/g 「a」で始まる文字をグローバル検索しますa$行の終わりを示す a で終わる任意の文字
モード 説明
^a 行の先頭を示す a で始まる任意の文字を使用します
/d$/ 数字で終わる /z$/g 「z」で終わる文字のグローバル検索
?=a / a( ?= b)/g 'a' の後に 'b' 文字が続くグローバル検索
?!a a が続かない任意の文字 /c( ?= d) /g 'c' の後に 'd' に続かない文字をグローバル検索します

6、字符串和正则配合。

   (1)、search()配合正则

  实例:找出字符串中第一次出现数字的位置

 <script>
 var str=&#39;asdf  zxcvbnm&#39;;
 //元字符\d,表示转义为数字
 var re=/\d/;
 alert(str.search(re));  //返回: 第一个数字为出现在第位
 </script>

   (2)、match()配合正则

  其实没有什么东西是非正则不可的,只是正则可以让做东西更方便。下面就完成本章遗留的历史问题,怎么使用正则,能一句代码就完成普通方法需要很多行代码才能完成的东西。

  在实例之前,先看看match()与正则的配合。

<script>
 var str=&#39;asdf  zxcvm&#39;;
 //找出字符串中的数字可以使用元字符\d
 var re=/\d/;
 //没告诉系统要找多少数字,系统在找到数字后就返回
 alert(str.match(re));  //返回:
 //因此需要全局匹配,使用修饰符g
 var re=/\d/g;
 //没告诉系统要找几位,系统会将所有找到的数字返回
 alert(str.match(re));  //返回:,,,,,,,,,,,,
 //所以可以使用两个元字符,告诉系统要找的数字是位
 var re=/\d\d/g;
 //显然这样是不可取的,因为数字的位数并不固定,可能是位,有可能还是多位
 alert(str.match(re));  //返回:,,,,
 //所以需要用到量词+,+代表若干,也就是多少都可以。
 var re=/\d+/g;
 //现在返回正确。
 alert(str.match(re));  //返回:,,,,
 </script>

   实例:使用正则找出字符串中所有数字

 <script>
 var str=&#39; abc d aa c zz -=-=s-&#39;;
 //alert(str.match(/\d+/g));
 //元字符\d也可以使用[-]代替,到随便哪个都行。
 alert(str.match(/[-]+/g));  //返回:,,,,,,,
 </script>

  正则是强大的字符串匹配工具,就这样简单的使用一句代码就完成了。

  (3)、replace()配合正则

 <script>
 var str=&#39;abc zaaz deaxcaa&#39;;
 //将字符串中的a替换为数字
 alert(str.replace(&#39;a&#39;, ));  //仅仅只将第一个a替换为
 //配合正则使用匹配所有a再替换
 var re=/a/g;
 alert(str.replace(re, &#39;&#39;));  //返回所有的a都为
 </script>

   实例:简单的敏感词过滤

  所谓的敏感词,就是法律不允许的词语,一切非法词都可以叫做敏感词,这包括的范围就太广了,比如危害国家安全,反对宪法确立的基本原则,散步谣言,扰乱民心,扰乱社会秩序,破坏社会稳定,色情、暴力、赌博、虚假、侵害、骚扰、粗俗、猥亵或其他道德上令人反感的词,以及含有法律规定或禁止的其他内容的词语。在平时最常见也是大多数人都会用的词莫属道德上令人反感的词了,说斯文一点就是吵架时用于攻击别人的词语。这里就列举几个热门的网络词语作为例子。

 <!DOCTYPE html>
 <html>
 <head>
   <meta charset="UTF-">
   <title>JavaScript实例</title>
 <script>
 window.onload=function (){
   var oBtn=document.getElementById(&#39;btn&#39;);
   var oTxt=document.getElementById(&#39;txt&#39;);
   var oTxt=document.getElementById(&#39;txt&#39;);
   oBtn.onclick=function (){
     //这里的|在正则中表示 或 的意思
     var re=/元芳|萌萌哒|然并卵|毛线|二货|城会玩/g;
     //文本框的值等于文本框的值过滤掉敏感词
     oTxt.value=oTxt.value.replace(re,&#39;***&#39;);
   };
 };
 </script>
 </head>
 <body>
 <textarea id="txt" rows="" cols=""></textarea><br>
 <input id="btn" type="button" value="过滤"><br>
 <textarea id="txt" rows="" cols=""></textarea>
 </body>
 </html>

  可在第一个文本框中输入一些相关语句,点击过滤按钮,查看过滤后的效果。

  此外,支持正则表达式的 String 对象的方法还包括 split() 方法,可把字符串分割为字符串数组。

7、RegExp对象方法。

  在JS中,RegExp对象是一个预定义了属性和方法的正则表达式对象。

  (1)、test()

  test() 方法用于检测一个字符串是否匹配某个模式,也就是检测指定字符串是否含有某个子串,如果字符串中含有匹配的文本,返回 true,否则返回 false。

  语法:RegExpObject.test(str)

  调用 RegExp 对象 re 的 test() 方法,并为它传递字符串str,与这个表示式是等价的:(re.exec(str) != null)。

  实例:搜索字符串是否含有指定的字符

 <script>
 var str=&#39;The best things in life are free, like hugs, smiles, friends, kisses, family, love and good memories.&#39;;
 var re=/i/;
 alert(re.test(str));  //返回:true
 var reg=/z/;
 alert(reg.test(str));  //返回:false
 //上面的代码可以不用定义正则的变量,直接使用,将两行合并为一行。
 alert(/i/.test(str));
 alert(/z/.test(str));
 </script>

  (2)、exec()

  exec() 方法用于检索字符串中的正则表达式的匹配,提取指定字符串中符合要求的子串,该方法返回一个数组,其中存放匹配的结果。如果未找到匹配,则返回 null。可以使用循环提取所有或者指定index的数据。

  语法:RegExpObject.exec(str)

  exec() 方法的功能非常强大,它是一个通用的方法,可以说是test() 方法的升级版,因为他不仅可以检测,而且检测到了可以直接提取结果。该方法使用起来比 test() 方法以及支持正则表达式的 String 对象的方法更为复杂。

 <script>
 var str = &#39;good good study day day up&#39;;
 var re = /good/;
 var arr = re.exec(str);
 console.log(arr);  //控制台显示:["good"]点开后显示: "good",index ,input "good good study day day up"。
 console.log(arr.index);  //控制台显示:
 console.log(arr.input);  //控制台显示:good good study day day up
 </script>

  通过上面的实例,可以看到,如果 exec() 找到了匹配的文本,则返回一个结果数组。否则,返回 null。此数组的第 0 个元素是与正则表达式相匹配的文本,第 1 个元素是与 RegExpObject 的第 1 个子表达式相匹配的文本(如果有的话),第 2 个元素是与 RegExpObject 的第 2 个子表达式相匹配的文本(如果有的话),以此类推。

  除了数组元素和 length 属性之外,exec() 方法还返回两个属性。index 属性声明的是匹配文本的第一个字符的位置。input 属性则存放的是被检索的字符串 string。我们可以看出,在调用非全局的 RegExp 对象的 exec() 方法时,返回的数组与调用方法 String.match() 返回的数组是相同的。 

  什么是"与子表达式相匹配的文本"?

  所谓的子表达式就是正则表达式中包含在圆括号中的内容。看下面实例:

 <script>
 var str = &#39;good good study day day up&#39;;
 var re = /g(o+)d/;
 var arr = re.exec(str);
 console.log(arr);  //显示:["good", "oo"]点开后显示: "good", "oo", index ,input: "good good study day day up"
 console.log(arr.length); //显示:
 var reg = /(o+)/;
 //var reg = /o+/;  只返回一个"oo",长度为
 var arr = reg.exec(str);
 console.log(arr);  //显示:["oo", "oo"]点开后显示: "oo", "oo", index ,input: "good good study day day up"
 console.log(arr.length); //显示:
 </script>

   通过上例,可以看到,子表达式是一个大的表达式的一部分,并且必须用()包含起来。一个表达式可使用多个子表达式,同时还支持多层嵌套,把一个表达式划分为多个子表达式的目的是为了把那些子表达式当作一个独立的元素来使用。也就是说表达式中的子表达式可以作为整个表达式返回,也可以作为一个单独的表达式返回。所以上面的数组长度为 2。

  使用子表达式是为了提取匹配的子字符串,表达式中有几个()就有几个相应的匹配字符串,顺序会依照()出现的顺序依次进行,并且()中可以使用 或"|" 进行多个选择。也就是说可以使用()对字符进行分组,并保存匹配的文本。

  如果该方法使用全局匹配,则找到第一个指定字符,并存储其位置,如果再次运行 exec(),则从存储的位置(lastIndex)开始检索,并找到下一个指定字符,存储其位置。lastIndex属性是RegExp对象属性,是一个整数,标示开始下一次匹配的字符位置。看下面实例:

 <script>
 var str = &#39;good good study day day up&#39;;
 var re = /good/g;
 var arr;
 do{
   arr = re.exec(str);
   console.log(arr);
   console.log(re.lastIndex);
 }
 while(arr !== null)
 /*
 结果如下:
 显示:["good"],点开后: "good", index , input "good good study day day up"。
 lastIndex为。
 显示:["good"],点开后: "good", index , input "good good study day day up"。
 lastIndex为。
 
 显示:null 
 lastIndex为。
 */
 </script>

   在调用非全局的 RegExp 对象的 exec() 方法时,返回的数组与调用 String.match() 返回的数组是相同的。但是,当 RegExpObject 是一个全局正则表达式时,exec() 的行为就稍微复杂一些。它会在 RegExpObject 的 lastIndex 属性指定的字符处开始检索字符串 string。当 exec() 找到了与表达式相匹配的文本时,在匹配后,它将把 RegExpObject 的 lastIndex 属性设置为匹配文本的最后一个字符的下一个位置。这就是说,可以通过反复调用 exec() 方法来遍历字符串中的所有匹配文本。当 exec() 再也找不到匹配的文本时,它将返回 null,并把 lastIndex 属性重置为 0。

  通过上面实例,可以看到,当第三次循环时,找不到指定的 "good",于是返回null,lastIndex值也变成0了。找到的第一个"good"的lastIndex值为4,是匹配文本最后一个字符的下一个位置。

<script>
 var str = &#39;good good study day day up&#39;;
 var re = /good/g;
 var arr;
 while((arr = re.exec(str)) != null){
   console.log(arr);
   console.log(re.lastIndex);
 }
 /*
 结果如下:
 显示:["good"],点开后: "good", index , input "good good study day day up"。
 lastIndex为。
 
 显示:["good"],点开后: "good", index , input "good good study day day up"。
 lastIndex为。
 */
 </script>

  这里需要注意,如果在一个字符串中完成了一次模式匹配之后要开始检索新的字符串(仍然使用旧的re),就必须手动地把 lastIndex 属性重置为 0。

  无论 RegExpObject 是否是全局模式,exec() 都会把完整的细节添加到它返回的数组中。这就是 exec() 与 String.match() 的不同之处,后者在全局模式下返回的信息要少得多。因此可以这么认为,在循环中反复地调用 exec() 方法是唯一一种获得全局模式的完整模式匹配信息的方法。

  (3)、compile

  compile() 方法用于在脚本执行过程中编译正则表达式,也可用于改变和重新编译正则表达式。主要作用是改变当前(re)匹配模式。

  语法:RegExpObject.compile(模式, 修饰符)

  模式就是正则表达式,修饰符用于规定匹配的类型,g匹配全局,i忽略大小写,gi全局匹配忽略大小写。

  该方法是改变匹配模式时使用的,一般情况下,能用到的地方很少。

  实例:在全局中忽略大小写 搜索"day",并用 "天" 替换,然后通过compile()方法,改变正则表达式,用 "日" 替换 "Today" 或 "day"。

 <script>
 var str = &#39;Today is a beautiful day, Day day happy!&#39;;
 var re = /day/gi;
 var str = str.replace(re, &#39;天&#39;);
 console.log(str);  //输出:To天 is a beautiful 天, 天 天 happy!
 reg = /(to)?day/gi;
 reg.compile(reg); 
 str = str.replace(reg, &#39;日&#39;);
 console.log(str);  //输出:日 is a beautiful 日, 日 日 happy!
 </script>

8、正则应用。

  正则表达式也叫规则表达式,所以在编写时,和编写JS的流程一样,先虑再写。最重要的就是,要搞清楚他所要表达的规则,先仔细端详其外表,看他到底长的什么模样,也就是以什么样的格式存在,再根据这种格式去写表达式,看是否能达到我们预期的目的,如果未达到,其实一般情况下直接将格式描述成表达式,都不会达到预期的效果,好在我们的主框架已经有了,我们只需要知道是什么地方出错了,什么地方没有达到预期,就可以很简单的在这个框架基础上稍加修改,最后就是完美的表达式了。比如要写一个验证手机号的正则表达式,手机号大家都知道是11位,全部为数字,而且开头是1,紧跟着的2位,因为运营商不同,可有多种组合,后面8位是任意数字,所以我们就可以规定开头必须为1,后面2位根据各运营商提供的不同组合进行限定,最后再输入8位任意数字。这样主框架就算完成了,但是手机号也有特殊情况,比如移动给手机号码前边加上+86依然可以使用,必要的时候我们还需要把这种情况考虑进去,不然用户输入了自己的移动手机号给前边加了个+86,然后点击提及,系统 "啪" 弹出一个窗口,你输入的是毛线,系统不识别,这样就闹笑话了,所以再只需要对框架做出修改,把这种情况考虑进去,就大功告成了。

  这么说起来正则表达式貌似很简单的样子,其实挺难的,why are you so diao?归根结底就是这种一般人很难看懂的表达方式,自己当时写的时候很明白表达的是什么,过段时间回头,哎哟我去,怎么不认识了。其实这是一个熟能生巧的过程,记得有篇课文中写到“好记性不如烂笔头”,勤能补拙,多动手多写多思考,通过码海战术,反复推敲代码,让自己身经百战,见的多了,自然就不虚了,编程是一门艺术,精通任何一门艺术,都需要大量的练习和领悟,知识就是一个积累的过程,当然更重要的还是要自己去总结归纳,让知识真正属于自己。我觉着写程序这东西吧,最重要的还是思维,让代码始终跟着这种思维走,目的只有一个,怎么简单怎么省事怎么做,当然不是偷工减料,要明白需要什么,不需要什么,要呈现出什么样的效果,应该怎么去一步步实现,只要有这种实现目的的思维,就可以让代码始终保持着清晰简洁的状态,加快编写代码的效率,还有助于排错,也有利于代码的优化。那个好像扯太远了,每个人都有自己思考问题的方式,有不同的做事风格,只要最优化解决问题就好了,回到正事,接下来看看正则表达式应用的两个实例。

  (1)、正则验证QQ号。

  思路分析:QQ号有一个特性全部为数字,而且第一位不为0,那么就可以这样写/^[1-9]/,开头为1-9随便哪个数字,常见的QQ号最少的是5位数,最多的是10位数,那么可以使用量词{n,m}限定位数,表达式为/\d{5,10}/,这有一个小问题,前边我们已经限定了开头的第一位,那就说明还可以再输入至少4位,最多9位的数字,这样才匹配了最少5位最多10位,将表达式改为/\d{4,9}/,最后再限定结尾不能是非数字,就完事了。下面看代码是怎么完成的:

<!DOCTYPE html>
 <html>
 <head>
   <meta charset="UTF-">
   <title>JavaScript实例</title>
 <script>
 window.onload = function (){
   var oBtn = document.getElementById(&#39;btn&#39;);
   oBtn.onclick = function (){
     var oTxt = document.getElementById(&#39;txt&#39;).value;
     var re=/^[-]\d{,}$/;
     //用定义的正则表达式检测输入框的值是否匹配。
     if(re.test(oTxt)){  
       alert("格式正确");
     }
     else{
       alert(&#39;输入错误&#39;);
     }
   };
 };
 </script>
 </head>
 <body>
 <input id="txt" type="text" placeholder="请输入QQ">
 <input id="btn" type="button" value="验证">
 </body>
 </html>

  (2)、正则验证邮箱。

  思路分析:先端详下邮箱的外表,随便来个abc123_@ss789.xyz,邮箱是典型的粗俗的分析下其结构组成,大致可分为五部分,第一部分若干字母、若干数字还有一个下划线,第二部分是一个@,第三部分又是若干字母、若干数字,第四部分是一个点,最后一部分又是若干字母,诶、邮箱长的好复杂,各种若干。现在我们看光了邮箱的模样,清楚了邮箱的规则,就可以使用表达式描述了,第一部分可写为/\w+/,表示若干英文,第二部分就采用@,第三部分可表达为[a-z0-9]+,若干字母数字都可以,第四部分需要注意,点在正则中代表任意字符,如果想直接显示为点,就需要使用转义,就写为\.,最后一部分若干英文,表达为[a-z]+,这样就用正则的规则把邮箱的规则描述完了,最后再使用忽略大小写,将格式整理下:/\w+@[a-z0-9]+\.[a-z]+/  下面就用我们分析的表达式直接验证一下:

 <!DOCTYPE html>
 <html>
 <head>
   <meta charset="UTF-">
   <title>JavaScript实例</title>
 <script>
 window.onload=function (){
   var oBtn=document.getElementById(&#39;btn&#39;);
   var oTxt=document.getElementById(&#39;txt&#39;);
   oBtn.onclick=function (){
     var re=/\w+@[a-z-]+\.[a-z]+/i;
     if(re.test(oTxt.value)){
       alert(&#39;合法邮箱&#39;);
     }
     else{
       alert(&#39;非法邮箱&#39;);
     }
   };
 };
 </script>
 </head>
 <body>
 <input id="txt" type="text" placeholder="请输入邮箱">
 <input id="btn" type="button" value="验证">
 </body>
 </html>

  将我们上面用于分析的邮箱例子abc123_@ss789.xyz拿来检测,OK,合法邮箱,这就没问题了吗?我们再来验证下这个邮箱:正则abc123_@ss789.xyz校验,OK,还是合法邮箱,这邮箱看着都不正规,跟我们之前分析的邮箱样子,长的从本质上都不一样,正则怎么会判断合法呢?这不是我们要的效果,显然是我们的表达式有点小问题,就像之前说的,一般情况下直接将格式描述成表达式,都不会达到预期的效果,那怎么解决呢?先开分析下是什么原因导致的,其实因为正则对象方法test()造成的,该方法有一个特性:只要这个字符串其中的一部分符合要求,就返回true。解决方法其实也很简单,让整个字符串都被正则检测,而不只是检测一部分,所以再加上行首行尾就OK了。其实熟练了正则之后,像这样的小问题,一般也不可能出现,这里的注重点是思路,要养成一种编写代码的思维模式。

 <!DOCTYPE html>
 <html>
 <head>
 <meta charset="UTF-">
 <title>JavaScript实例</title>
 <script>
 window.onload=function (){
   var oBtn=document.getElementById(&#39;btn&#39;);
   var oTxt=document.getElementById(&#39;txt&#39;);
   oBtn.onclick=function (){
     var re=/^\w+@[a-z-]+\.[a-z]+$/i;
     if(re.test(oTxt.value)){
       alert(&#39;合法邮箱&#39;);
     }
     else{
       alert(&#39;非法邮箱&#39;);
     }
   };
 };
 </script>
 </head>
 <body>
 <input id="txt" type="text" placeholder="请输入邮箱">
 <input id="btn" type="button" value="验证">
 </body>
 </html>

现在对刚才的2个邮箱再次验证,第一个合法,第二个非法,这个正则验证邮箱的表达式就没问题了。其实还是不够严谨,现在网站大多要填邮箱的地方,邮箱的服务器地址也就是后缀名如@qq.com等都提供了下拉列表,可供用户选择,如果是需要整个邮箱都自行输入,那么这个正则表达式问题就来了,邮箱的后缀名可以分为几类,其第三部分和最后一部分都是固定的格式,如果使用该表达式验证,那事就大了,因为我们给每一部分定义的都是可输入若干,很显然这是非法的格式,邮箱的后缀是需要做限定的,这里只是简单的做一个实现思路的分析,在真正用的时候,还需要具体问题具体对待。像这种需要验证的东西,前端不可能做到完美,前端就算写的再严谨,也是很容易出问题的,所以这是属于后端干的事,但是前端可以对用户的输入做一个简单的格式验证,只有确保用户输入正确了,再配合后端,那就是事半功倍的。

PS:RegExp几个常用方法说明

1、Test()

RegExpObject.test(string)

判断string中是否有与表达式匹配的字符串,有则返回true,否则返回false
例如

var patt1=new RegExp("e");    
document.write(patt1.test("The best things in life are free"));

 
由于该字符串中存在字母 "e",以上代码的输出将是:true

2、exec()

RegExpObject.exec(string)
exec() 方法检索字符串中的指定值。返回值是被找到的值。如果没有发现匹配,则返回 null。

例如

JScript 代码 

var str= "cat2,hat8" ;
var reg=/c(at)\\d/ ; 有分组
console.info(reg.exec(str));//运行返回  ["cat2", "at"]

3、Match()

string.match(RegExpObject)
它和exec有类似,也是返回一个数组,但它们有区别。
区别1:如下如果正则中有g,则match返回所有匹配。而exec永远只返回与第一个匹配有关的信息。
区别2:如果没有g,但是有分组,则两个结果一样。或者没有g也没有分组。只返回第一个匹配。

实例

JScript 代码

var someText= "web2.0 .net2.0" ;
var pattern=/(\\w+)(\\d)\\.(\\d)/g;
var outCome_exec=pattern.exec(someText); ["web2.0","web","2","0"]
var outCome_matc=someText.match(pattern); ["web2.0","net2.0"]

4、Search()

stringObject.search(regexp)

返回第一个匹配的起始位置。

5、Replace()

stringObject.replace(regexp/substr,replacement)


返回新替换过后的新字符串。
如果是字符串,替换第一个。如果是正则表达式中有g,则全部替换,否则也是一个。

例如

JScript 代码

function fn() { 
for(var i = 0;i < arguments.length;i++){
alert("第"+(i+1)+"个参数的值:"+arguments[i]);
} 
} 
var str = &#39;<p id="{wo}" >{ni}</p>&#39;; 
str.replace(/\\{([a-z]+)\\}/ig, fn);

 6、Split()

stringObject.split(separator,howmany)


第一个参数是字符串或者正则表达式,从它开始分解字符串。第二个参数表示返回数组的最大长度。

例如 

JScript 代码 

var str= "cat2,hat8" ;
var reg=/at/ ;
console.info(str.split(reg));
["c", "2,h", "8"]
console.info(str.split(reg,2));
["c", "2,h"]

7、compile()

compile() 方法用于改变 RegExp。
compile() 既可以改变检索模式,也可以添加或删除第二个参数。

例如 

JScript 代码

var patt1=new RegExp("e");  
document.write(patt1.test("The best things in life are free"));  
patt1.compile("d");  
document.write(patt1.test("The best things in life are free"));

8、关于$0~$99的例子

JScript 代码

var str="alert.login.verifyfailed=Your email or password is incorrect!";
var reg=/^alert.\\w*(.\\w*)=((?:\\w*[ !\\.])*)$/;
var out=str.match(reg);
console.info($0);

9、测试RegExp属性

JScript 代码 

function demo(){
  var str = "abcdd abcsszabcdddccabAbcddABCEE";
  var regex = /a(bc)/gi;
  var t = null;
  while(t = regex.exec(str)){
    var result = "index = " + t.index + ", match = " + t[0] + ", group = " + t[1];
    result += "/n$1=" + RegExp.$1 + ", lastMatch=" + RegExp.lastMatch + ", leftContext=" + RegExp.leftContext;
    alert(result);
  }
}


以上就是JavaScript,学习小结, RegExp的内容,更多相关内容请关注PHP中文网(www.php.cn)!



声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。