ホームページ >ウェブフロントエンド >jsチュートリアル >JavaScript学習まとめ(7) JS RegExp_javascriptスキル
jsでは正規表現はRegExpオブジェクトで表されます。 RegExpとは正規表現の略です。 RegExp の単純なパターンは 1 文字にすることができます。より複雑なパターンにはより多くの文字が含まれており、解析、形式チェック、置換などに使用できます。 RegExp() コンストラクターを使用して RegExp オブジェクトを作成することも、リテラル構文を使用することもできます。
1. RegExp の概要。
RegExp は正規表現 (コードでは regex、regexp、または RE/re/reg と略されることが多い正規表現) であり、単一の文字列を使用して、特定の構文ルールに準拠する一連の文字列検索パターンを記述し、一致させます。検索モードはテキスト検索とテキスト置換に使用できます。
正規表現は、一連の文字で構成される検索パターンであり、テキスト内のデータを検索するときに、その検索パターンを使用してクエリする内容を記述することができます。つまり、正規表現はオブジェクトです。これは文字パターンを記述し、文字列パターンの一致と検索および置換を実行するための強力なツールです。
いわゆる正規表現は、コンピュータが理解できる一定の規則を表すルールまたはパターン表現として直接理解できますが、一般の人には理解するのが難しいテキスト表現に使用できます。すべてのテキスト検索とテキスト置換の操作は、簡単に言うと文字列を処理することです。
2. 文字列メソッド。
(1), charAt() 特定の文字を取得し、文字列内の特定の文字を返します。
(2)、split() 文字列を分割して配列を取得します。
(3)、search() ある文字が最初に出現する位置を検索します。 戻り値は数値で、見つからない場合は-1を返します。
(4)、match() 文字列内で指定された文字を検索し、その文字を返します。正規表現を使用しない場合は、指定された文字の最初の出現のみが返され、後方一致は実行されません。正規表現を使用してグローバル マッチングを実行する場合、文字列内の指定されたすべての文字を配列形式で返します。見つからない場合は null を返します。
(5)、replace() 文字を置換し、新しい文字列を返します。正規表現と組み合わせて使用すると、すべての一致を置換できます。
<script> var str='abcdefgca'; //返回字符串中某一位的字符。 alert(str.charAt()); //返回:d //查找字符串首次出现的位置。 alert(str.search('z')); //返回:- //查找指定的字符。 //只返回第一次出现的c,不再向后匹配。 alert(str.match('c')); //返回:c //将'a'替换为'i'。 //只替换了第一个位置的a,不再向后匹配。 alert(str.replace('a', 'i')); //返回:ibcdefgca //分割字符串。 var str='--aaa--cd'; var arr=str.split('-'); //返回:,,aaa,,cd alert(arr); </script>
例: 通常の方法を使用して文字列内のすべての数値を検索します
実装のアイデア: 文字列内の数値を見つけるのは難しくありません。最初に文字列内の数値を抽出するために判断を使用します。その後、文字列内に複数の数値が存在する必要があるため、それを格納するには空の文字列が必要です。数値を抽出し、それらの数値を配列に追加し、最後に戻ると完了です。プログラムがどのように実装されるかを見てみましょう:
<script> var str=' abc d aa c zz -=-=s-'; var arr=[]; var num=''; //首先循环遍历字符串 for(var i=;i<str.length;i++){ //再判断当前字符大于等于并且小于等于,则为数字 if(str.charAt(i)>='' && str.charAt(i)<=''){ //那么就将当前的字符存储在空字符串中 num += str.charAt(i); } else{ //如果字符串中有值。 if(num){ //将值添加到数组中。 arr.push(num); //再清空字符串,避免重复添加。 num=''; } } } //最后在整个字符串结束之后有可能还会有数字,再做一次判断。 if(num){ //如果还有值就添加到数组中。 arr.push(num); //再清空字符串。 num=''; } //返回:OK,现在返回就完成了。 alert(arr); //返回:,,,,,,, </script>
通常の方法で完了でき、構造も明確ですが、正規表現を使用すると、非常に多くの作業を 1 つの式で完了できるため、その方法を見てみましょう。正規表現を使用します。
3. 通常のルールを使用します。
正規表現の構文: var re = new RegExp('pattern', 'modifier');
パターンは式のパターンであり、修飾子はグローバル マッチング、大文字と小文字の区別などを指定するために使用されます。完全な形式は正規表現です。
通常の構文はこんな感じですね、JSで新しく作成するオブジェクトの典型的な構文ではないでしょうか? ちなみに、通常のオブジェクトを新規に作成するという意味です。 new キーワードの使用は避けるべきであることは誰もが知っていますが、new を使用すると間違いなく新しいオブジェクトが作成され、適切に処理しないと過剰な蓄積によりメモリ オーバーフローが発生することになります。リソースが非常に高価であり、コードの最適化の実装には役立ちません。同時に、この書き方は規則性を反映していないため、実際の使用では、次のような別のスタイルが使用されます。 🎜>
構文: var re = /mode/modifier;このスタイルは比較的簡潔で、一般の人には理解できない表現方法です。
(1)、修飾語。
修飾子は、グローバル マッチングと大文字小文字の区別を実行するために使用されます。
大文字を無視する: i (ignore の略語、中国語訳は無視する)
グローバルマッチング: g (グローバルの略語、中国語訳: all/global)
例: 指定された文字のグローバル検索
<script> var str='AbCdEFgiX'; //JS风格: //这个正则表达式什么也不代表,只代表abc本身。 var reg=new RegExp('abc', 'i'); alert(str.match(reg)); //返回:AbC //常用风格: var re=/efg/i; alert(str.match(re)); //返回:EFg </script>
4. 角括弧とメタキャラクター。
(1)、かぎ括弧。角括弧は、特定の範囲内の文字を検索するために使用されます。
①、任意の文字
式: [abc]
角かっこ内の任意の文字を検索します。
ここでの [] は、または、どちらが表示されてもよいという意味です。
<script> var str='apc xpc ppc bpc spc opc'; //[apx]pc,随便出现哪个都行,即:apc ppc xpc var re=/[apx]pc/g; alert(str.match(re)); //返回前个pc。 </script>
②、范围查找。
表达式:[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='ot out o.t o t o`t ot ot'; //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] 文字と数字以外なら何でもOKです。
(2)メタキャラクター。
メタキャラクターは特別な意味を持つ文字であり、エスケープ文字とも呼ばれます。
以下は、一般的に使用されるメタキャラクターの一部です:
メタキャラクター | 説明 | を使用します |
. | 改行と行終端記号を除く任意の文字を表す単一の文字を検索します。 | 問題が発生しやすいため、使用はお勧めしません。 |
w | [a-z0-9] | に相当する、英語の数字やアンダースコアを含む単語文字を検索します。/w/ |
W | [^a-z0-9] | に相当する非単語文字を検索します。/W/ |
d | [0-9] に相当する数値を検索します | /d/ |
D | [^0-9] に相当する非数字を検索します | /D/ |
の | スペース、キャリッジリターン、タブ、ラインフィード、フォームフィードを含む空白文字を検索します。印刷できない文字は表示できません。 | /s/ |
S | 空白以外の文字を検索します。 | /S/ |
b | 単語の先頭または末尾で一致を検索します。一致が見つからない場合は null を返します。 | /b/ |
B |
単語の境界ではない一致を検索します。つまり、一致する位置の前の文字と次の文字の種類が同じです。つまり、両方とも単語である必要があります。 、 または両方が非単語である必要があります。文字列の先頭と末尾の は非単語文字とみなされ、一致しない場合は null が返されます。 |
/B/ |
n | 改行文字を検索し、見つかった場合はその位置を返し、見つからない場合は -1 を返します。 | /n/ |
f | 改ページを検索します。 | /f/ |
r | 復帰文字を探します。 | /r/ |
t | タブ文字を検索します。 |
5. 数量子。
いわゆる量指定子は量指定子、つまり数値であり、出現回数を表すために正規表現で使用されます。
以下は、一般的に使用される数量詞の一部です:
数量子 | 説明 | を使用します |
* | 0 回または任意の回数 ({0,} | と同等)範囲が広すぎて正確さが不十分であるため、推奨されません。 |
? | 0 回または 1 回、{0, 1} に相当 | /10?/g 直後にゼロまたは 1 つの '0' を含む、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 桁の数値を含むグローバル検索を実行します。 |
次に、一般的に使用される一致パターンをいくつか示します:
モード | 説明 | を使用します |
^a | a で始まる文字は行の先頭を意味します | /^d/ 数字で始まります /^a/g 'a' で始まる文字のグローバル検索 |
$ | 行の終わりを示す a で終わる任意の文字 | /d$/ 数字で終わる /z$/g 'z' で終わる文字のグローバル検索 |
?=a | が続く任意の文字 | /a(?= b)/g 'a' に続いて 'b' 文字をグローバル検索 |
?!a | が続かない任意の文字 | /c(?= d)/g 'c' の後に 'd' に続かない文字をグローバル検索します |
6、字符串和正则配合。
(1)、search()配合正则
实例:找出字符串中第一次出现数字的位置
<script> var str='asdf zxcvbnm'; //元字符d,表示转义为数字 var re=/\d/; alert(str.search(re)); //返回: 第一个数字为出现在第位 </script>
(2)、match()配合正则
其实没有什么东西是非正则不可的,只是正则可以让做东西更方便。下面就完成本章遗留的历史问题,怎么使用正则,能一句代码就完成普通方法需要很多行代码才能完成的东西。
在实例之前,先看看match()与正则的配合。
<script> var str='asdf zxcvm'; //找出字符串中的数字可以使用元字符\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=' abc d aa c zz -=-=s-'; //alert(str.match(/\d+/g)); //元字符d也可以使用[-]代替,到随便哪个都行。 alert(str.match(/[-]+/g)); //返回:,,,,,,, </script>
正则是强大的字符串匹配工具,就这样简单的使用一句代码就完成了。
(3)、replace()配合正则
<script> var str='abc zaaz deaxcaa'; //将字符串中的a替换为数字 alert(str.replace('a', )); //仅仅只将第一个a替换为 //配合正则使用匹配所有a再替换 var re=/a/g; alert(str.replace(re, '')); //返回所有的a都为 </script>
实例:简单的敏感词过滤
所谓的敏感词,就是法律不允许的词语,一切非法词都可以叫做敏感词,这包括的范围就太广了,比如危害国家安全,反对宪法确立的基本原则,散步谣言,扰乱民心,扰乱社会秩序,破坏社会稳定,色情、暴力、赌博、虚假、侵害、骚扰、粗俗、猥亵或其他道德上令人反感的词,以及含有法律规定或禁止的其他内容的词语。在平时最常见也是大多数人都会用的词莫属道德上令人反感的词了,说斯文一点就是吵架时用于攻击别人的词语。这里就列举几个热门的网络词语作为例子。
<!DOCTYPE html> <html> <head> <meta charset="UTF-"> <title>JavaScript实例</title> <script> window.onload=function (){ var oBtn=document.getElementById('btn'); var oTxt=document.getElementById('txt'); var oTxt=document.getElementById('txt'); oBtn.onclick=function (){ //这里的|在正则中表示 或 的意思 var re=/元芳|萌萌哒|然并卵|毛线|二货|城会玩/g; //文本框的值等于文本框的值过滤掉敏感词 oTxt.value=oTxt.value.replace(re,'***'); }; }; </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='The best things in life are free, like hugs, smiles, friends, kisses, family, love and good memories.'; 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 = 'good good study day day up'; 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 = 'good good study day day up'; 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 = 'good good study day day up'; 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 = 'good good study day day up'; 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 = 'Today is a beautiful day, Day day happy!'; var re = /day/gi; var str = str.replace(re, '天'); console.log(str); //输出:To天 is a beautiful 天, 天 天 happy! reg = /(to)?day/gi; reg.compile(reg); str = str.replace(reg, '日'); console.log(str); //输出:日 is a beautiful 日, 日 日 happy! </script>
8. 通常のアプリケーション。
正規表現は正規表現とも呼ばれるので、書くときはJSを書くのと同じ手順で、まず考えてから書きます。最も重要なことは、表現したいルールを理解することです。まず、それがどのような形式であるかを注意深く観察し、その形式に従って表現できるかどうかを確認します。期待した目的を達成しない場合、実際には、一般に形式を式として直接記述しても期待した効果は得られないため、何が問題であったのかを知る必要があるだけです。 , この枠組みをベースに少し修正を加えるだけで、最終的には完璧な表現が完成します。たとえば、携帯電話番号を検証するための正規表現を作成する場合、携帯電話番号は 11 桁であり、すべての数字が先頭で 1 で、その後に 2 桁が続くことは誰もが知っています。演算子が異なるためです。数字は任意の数字であるため、最初は 1 である必要があり、次の 2 桁は各演算子が提供するさまざまな組み合わせに従って制限され、最後に 8 桁の任意の数字を入力することができます。このように、本体の枠組みが完成しても、必要に応じて携帯電話番号の前に86を付けるなどの特殊な事情も考慮する必要があります。そうでない場合は、ユーザーは自分の携帯電話番号を先頭に追加して、「Mention」をクリックする必要があります。入力した内容はシステムによって認識されません。なので、フレームワークを変更してこの状況を検討するだけで完了です。
正規表現はとても簡単そうに見えますが、実際には非常に難しいのはなぜですか?結局のところ、この種の表現は一般の人には理解しがたいものなのです。書いたとき、私はそれが何を表現しているのかを正確に理解しました。そして、しばらくして振り返って、ああ、何だろう、と思いました。私はそれを認識していますか?実際、これは練習によって完璧になるプロセスです。「良い記憶力は悪いペンほど良くない」という文章があったのを覚えています。