JavaScript インタビューの正規表現: 「id による要素の取得」をキャメルケースに変換する方法、よく使用されるメール アドレス、ID カード、QQ 番号などの情報を確認する方法など。
序文
正規表現は、文字列を照合するために使用されるテキスト パターンです。これには、修飾子、角括弧、括弧、メタ文字、および量指定子が含まれます。
正規表現では、複雑で意味のある正規文字列を使用して、特定の構文ルールのターゲット文字列と一致します。
1. はじめに
正規表現を作成するには 2 つの方法があります。
リテラル構文 | RegExp オブジェクトの構文 |
---|---|
/パターン/属性 | 新しい RegExp(パターン、属性) |
パラメータ パターン - 正規表現パターンまたはその他の正規表現を指定する文字列です。
パラメータ属性 - 属性「g」、「i」、および「m」を含むオプションの文字列で、それぞれグローバル マッチング、大文字と小文字を区別するマッチング、および複数行のマッチングを指定するために使用されます。
戻り値 - 指定されたモードとフラグを持つ新しい RegExp オブジェクト。引数のパターンが文字列ではなく正規表現の場合、RegExp() コンストラクターは、指定された RegExp と同じパターンとフラグを持つ新しい RegExp オブジェクトを作成します。
new 演算子を使用せずに RegExp() を関数として呼び出した場合、パターンが正規表現の場合、新しい RegExp オブジェクトを作成するのではなくパターンのみを返す点を除き、new 演算子を使用して呼び出した場合と同じように動作します。 。
説明:
SyntaxError - この例外は、パターンが有効な正規表現でない場合、または属性に「g」、「i」、および「m」以外の文字が含まれている場合にスローされます。
TypeError - pattern が RegExp オブジェクトであるが、attribute パラメータが省略されていない場合にスローされます。
var reg=/^a/;
typeof reg // "object"
正規表現の本質は、次のプロパティを持つオブジェクトです。
属性 | 説明する |
---|---|
グローバル | RegExp オブジェクトにフラグ g があるかどうか。 |
無視するケース | RegExp オブジェクトにフラグ i があるかどうか。 |
lastIndex | 次の一致を開始する文字位置を示す整数。 |
複数行 | RegExp オブジェクトにフラグ m があるかどうか。 |
ソース | 正規表現のソーステキスト。 |
2. マッチングルール
1.修飾子
修飾子 | 説明する |
---|---|
私 | 大文字と小文字を区別しないマッチングを実行します。 |
g | グローバル一致を実行します (最初の一致が見つかった後に停止するのではなく、すべての一致を検索します)。 |
メートル | 複数行のマッチングを実行します。 |
2.ブラケット
括弧は文字の範囲を検索するために使用されます。
表現 | 説明する |
---|---|
[ABC] | 角括弧内の文字を検索します。 |
[^abc] | 角括弧の間にない文字を検索します。 |
[0-9] | 0 から 9 までの任意の数字を見つけます。 |
[az] | 小文字の a から小文字の z までの任意の文字を検索します。 |
[AZ] | 大文字の A から大文字の Z までの任意の文字を検索します。 |
[アズ] | 大文字の A から小文字の z までの任意の文字を検索します。 |
[adgk] | 指定されたセット内の任意の文字を検索します。 |
[^adgk] | 指定されたセットの外にある文字を検索します。 |
(赤|青|緑) | 指定されたオプションを検索します。 |
角括弧と括弧の違い
/[ad]/.test('abs') // true
/(ad)/.test('abs') // false
/(a|d)/.test('abs') // true
/(^ab)/.test("ab") //true
/[^ab]/.test("ab") // false
上の表に示すように、角括弧には特別な意味があり、角括弧は内側全体が一致する文字であることを表し、角括弧内の特別な意味は括弧内では無効です。
3. メタキャラクター
メタキャラクターは特別な意味を持つ文字です。
メタキャラクター | 説明する |
---|---|
。 | 改行と行末文字を除く単一の文字を検索します。 |
\w | 単語の文字を検索します。 |
\W | 単語以外の文字を検索します。 |
\d | 数字を見つけます。 |
\D | 数字以外の文字を検索します。 |
\s | 空白文字を検索します。 |
\S | 空白以外の文字を検索します。 |
\b | 単語の境界を一致させます。 |
\B | 単語以外の境界と一致します。 |
\0 | NUL 文字を検索します。 |
\n | 改行文字を検索します。 |
\f | フォームフィード文字を検索します。 |
\r | 復帰文字を見つけます。 |
\t | タブ文字を見つけます。 |
\v | 垂直タブ文字を見つけます。 |
\xxx | 8 進数 xxx で指定された文字を検索します。 |
\xdd | 16 進数 dd で指定された文字を検索します。 |
\uxxxx | 16 進数 xxxx として指定された Unicode 文字を検索します。 |
4.数量子
数量詞 | 説明する |
---|---|
n+ | 少なくとも 1 つの n を含む任意の文字列と一致します。 |
な* | 0 個以上の n を含む任意の文字列と一致します。 |
ん? | 0 または 1 つの n を含む任意の文字列と一致します。 |
n{X} | 次のシーケンスを含む文字列と一致します。 |
n{X,Y} | X から Y n までのシーケンスを含む文字列と一致します。 |
n{X,} | 少なくとも X 個の n シーケンスを含む文字列と一致します。 |
n$ | n で終わる任意の文字列と一致します。 |
^n | n で始まる任意の文字列と一致します。 |
?=n | 指定された文字列 n の直後に続く任意の文字列と一致します。 |
?!n | 指定された文字列 n が直後に続かない任意の文字列と一致します。 |
3. 通常のインターセプト、文字列置換およびその他の操作
1.分割
语法:stringObject.split(separator,howmany)
separator 必需。字符串或正则表达式,从该参数指定的地方分割 stringObject。
howmany 可选。该参数可指定返回的数组的最大长度。如果设置了该参数,返回的子串不会多于这个参数指定的数组。如果没有设置该参数,整个字符串都会被分割,不考虑它的长度。
"2:3:4:5".split(":") //将返回["2", "3", "4", "5"]
"|a|b|c".split("|") //将返回["", "a", "b", "c"]
// 把单词分割为字母,或者把字符串分割为字符
"hello".split("") //可返回 ["h", "e", "l", "l", "o"]
// 只需要返回一部分字符,请使用 howmany 参数:
"hello".split("", 3) //可返回 ["h", "e", "l"]
// 特例
"2:3:4:5".split("a") //["2:3:4:5"]
"".split("a") // [""]
"".split("") // []
"2:3:4:5".split("") // ["2", ":", "3", ":", "4", ":", "5"]
说明:
返回值,是一个字符串数组,若separator没有匹配上,则返回一元本身字符串数组
2.replace
语法:stringObject.replace(regexp/substr,replacement)
regexp/substr 必需。规定子字符串或要替换的模式的 RegExp 对象。
replacement 必需。一个字符串值。规定了替换文本或生成替换文本的函数。
// $1 $2 $3的妙用
"Doe, John".replace(/(\w+)\s*, \s*(\w+)/, "$2 $1"); // "John Doe"
//花引号替换为直引号:
'"a", "b"'.replace(/"([^"]*)"/g, "'$1'"); // "'a', 'b'"
// 把字符串中所有单词的首字母都转换为大写:
'aaa bbb ccc'.replace(/\b\w+\b/g, function(word){
return word.substring(0,1).toUpperCase()+word.substring(1);}
);
// Aaa Bbb Ccc
var str = "get-element-by-id";
var reg = /-\w/g; // 匹配横杆以及之后的一个字符,全局匹配
str.replace(reg,function($0){
return $0.slice(1).toUpperCase();
// 匹配到到是-e -b -i 形式截取后一个字符转成大写
}); //"getElementById"
3.match
语法: stringObject.match(searchvalue)
stringObject.match(regexp)
searchvalue 必需。规定要检索的字符串值。
regexp 必需。规定要匹配的模式的 RegExp 对象。如果该参数不是 RegExp 对象,则需要首先把它传递给 RegExp 构造函数,将其转换为 RegExp 对象
"1 plus 2 equal 3".match(/\d+/g) // ["1", "2", "3"]
"1 plus 2 equal 3".match(/\d+/) // ["1", index: 0, input: "1 plus 2 equal 3", groups: undefined]
说明
match() 方法将检索字符串 stringObject,以找到一个或多个与 regexp 匹配的文本。这个方法的行为在很大程度上有赖于 regexp 是否具有标志 g。
如果 regexp 没有标志 g,那么 match() 方法就只能在 stringObject 中执行一次匹配。如果没有找到任何匹配的文本, match() 将返回 null。否则,它将返回一个数组,其中存放了与它找到的匹配文本有关的信息。该数组的第 0 个元素存放的是匹配文本,而其余的元素存放的是与正则表达式的子表达式匹配的文本。除了这些常规的数组元素之外,返回的数组还含有两个对象属性。index 属性声明的是匹配文本的起始字符在 stringObject 中的位置,input 属性声明的是对 stringObject 的引用。
如果 regexp 具有标志 g,则 match() 方法将执行全局检索,找到 stringObject 中的所有匹配子字符串。若没有找到任何匹配的子串,则返回 null。如果找到了一个或多个匹配子串,则返回一个数组。不过全局匹配返回的数组的内容与前者大不相同,它的数组元素中存放的是 stringObject 中所有的匹配子串,而且也没有 index 属性或 input 属性。
注意:在全局检索模式下,match() 即不提供与子表达式匹配的文本的信息,也不声明每个匹配子串的位置。如果您需要这些全局检索的信息,可以使用 RegExp.exec()。
四、正则校验字符串场景
(一)、校验数字
描述 | 表达式 |
---|---|
数字 | ^[0-9]*$ |
n位的数字 | ^\d{n}$ |
至少n位的数字 | ^\d{n,}$ |
m-n位的数字 | ^\d{m,n}$ |
零和非零开头的数字 | ^(0|[1-9][0-9]*)$ |
非零开头的最多带两位小数的数字 | ^([1-9][0-9]*)+(.[0-9]{1,2})?$ |
带1-2位小数的正数或负数 | ^(-)?\d+(\.\d{1,2})?$ |
正数、负数、和小数 | ^(-|+)?\d+(\.\d+)?$ |
有两位小数的正实数 | ^[0-9]+(\.[0-9]{2})?$ |
有1~3位小数的正实数 | ^[0-9]+(\.[0-9]{1,3})?$ |
非零的正整数 | ^[1-9]\d*$ 或 ^([1-9][0-9]){1,3}$ 或 ^\+?[1-9][0-9]$ |
非零的负整数 | ^\-[1-9][]0-9"$ 或 ^-[1-9]\d$ |
非负整数 | ^\d+$ 或 ^[1-9]\d*|0$ |
非正整数 | ^-[1-9]\d*|0$ 或 ^((-\d+)|(0+))$ |
非负浮点数 | ^\d+(\.\d+)?$ 或 ^[1-9]\d*\.\d*|0\.\d*[1-9]\d*|0?\.0+|0$ |
非正浮点数 | ^((-\d+(\.\d+)?)|(0+(\.0+)?))$ 或 ^(-([1-9]\d*\.\d*|0\.\d*[1-9]\d*))|0?\.0+|0$ |
正浮点数 | ^[1-9]\d*\.\d*|0\.\d*[1-9]\d*$ 或 ^(([0-9]+\.[0-9][1-9][0-9])|([0-9][1-9][0-9]\.[0-9]+)|([0-9][1-9][0-9]))$ |
负浮点数 | ^-([1-9]\d*\.\d*|0\.\d*[1-9]\d*)$ 或 ^(-(([0-9]+\.[0-9][1-9][0-9])|([0-9][1-9][0-9]\.[0-9]+)|([0-9][1-9][0-9])))$ |
浮点数 | ^(-?\d+)(\.\d+)?$ 或 ^-?([1-9]\d*\.\d*|0\.\d*[1-9]\d*|0?\.0+|0)$ |
(二)、校验字符
描述 | 表达式 |
---|---|
汉字 | ^[\u4e00-\u9fa5]{0,}$ |
英文和数字 | ^[A-Za-z0-9]+$ 或 ^[A-Za-z0-9]{4,40}$ |
长度为3-20的所有字符 | ^.{3,20}$ |
由26个英文字母组成的字符串 | ^[A-Za-z]+$ |
由26个大写英文字母组成的字符串 | ^[A-Z]+$ |
由26个小写英文字母组成的字符串 | ^[a-z]+$ |
由数字和26个英文字母组成的字符串 | ^[A-Za-z0-9]+$ |
由数字、26个英文字母或者下划线组成的字符串 | ^\w+$ 或 ^\w{3,20}$ |
中文、英文、数字包括下划线 | ^[\u4E00-\u9FA5A-Za-z0-9_]+$ |
中文、英文、数字但不包括下划线等符号 | ^[\u4E00-\u9FA5A-Za-z0-9]+$ 或 ^[\u4E00-\u9FA5A-Za-z0-9]{2,20}$ |
可以输入含有^%&’,;=?$\"等字符 | [^%&’,;=?$\x22]+ |
禁止输入含有~的字符 | [^~\x22]+ |
(三)、实际中特殊场景
描述 | 表达式 |
---|---|
Email地址 | ^\w+([-+.]\w+)*@\w+([-.]\w+)*.\w+([-.]\w+)*$ |
域名 | [a-zA-Z0-9][-a-zA-Z0-9]{0,62}(/.[a-zA-Z0-9][-a-zA-Z0-9]{0,62})+/.? |
InternetURL | [a-zA-z]+://[^\s]* 或 ^http://([\w-]+.)+[\w-]+(/[\w-./?%&=]*)?$ |
手机号码 | ^(13[0-9]|14[5|7]|15[0|\1|\2|3|5|6|7|8|9]|18[0|1|2|3|5|6|7|8|9])\d{8}$ |
电话号码(“XXX-XXXXXXX”、“XXXX-XXXXXXXX”、“XXX-XXXXXXX”、“XXX-XXXXXXXX”、"XXXXXXX"和"XXXXXXXX) | ^((\d{3,4}-)|\d{3.4}-)?\d{7,8}$ |
国内电话号码(0511-4405222、021-87888822) | \d{3}-\d{8}、|\d{4}-\d{7} |
电话号码正则表达式(支持手机号码,3-4位区号,7-8位直播号码,1-4位分机号) | ((\d{11})|^((\d{7,8})|(\d{4}|\d{3})-(\d{7,8})|(\d{4}|\d{3})-(\d{7,8})-(\d{4}|\d{3}|\d{2}|\d{1})|(\d{7,8})-(\d{4}|\d{3}|\d{2}|\d{1}))$) |
身份证号(15位、18位数字),最后一位是校验位,可能为数字或字符X | (^\d{15}$)|(^\d{18}$)|(^\d{17}(\d|X|x)$) |
帐号是否合法(字母开头,允许5-16字节,允许字母数字下划线) | ^[a-zA-Z][a-zA-Z0-9_]{4,15}$ |
密码(以字母开头,长度在6~18之间,只能包含字母、数字和下划线) | ^[a-zA-Z]\w{5,17}$ |
强密码(必须包含大小写字母和数字的组合,不能使用特殊字符,长度在8-10之间) | ^(?=.\d)(?=.[a-z])(?=.*[A-Z]).{8,10}$ |
日期格式 | ^\d{4}-\d{1,2}-\d{1,2} |
一年的12个月(01~09和1~12) | ^(0?[1-9] |
一个月的31天(01~09和1~31) | ^((0?[1-9]) |
xml文件 | ^([a-zA-Z]±?)+[a-zA-Z0-9]+\.[x|X][m|M][l|L]$ |
中文字符的正则表达式 | [\u4e00-\u9fa5] |
双字节字符 | [^\x00-\xff] (包括汉字在内,可以用来计算字符串的长度(一个双字节字符长度计2,ASCII字符计1)) |
空白行的正则表达式 | \n\s*\r (可以用来删除空白行) |
HTML标记的正则表达式 | <(\S*?)[^>]*>.*?|<.*? /> ( 首尾空白字符的正则表达式:^\s*|\s*$或(^\s*)|(\s*$) (可以用来删除行首行尾的空白字符(包括空格、制表符、换页符等等),非常有用的表达式) |
腾讯QQ号 | [1-9][0-9]{4,} (腾讯QQ号从10000开始) |
中国邮政编码 | [1-9]\d{5}(?!\d) (中国邮政编码为6位数字) |
IP地址 | ((?:\(?:25[0-5]|2[0-4]\d|[01]?\d?\d)\.){3}(?:25[0-5]|2[0-4]\d|[01]?\d?\d)) |
钱的输入格式 | 例如:最大13位整数,2位小数 包含千分位 ^\d{1,13}(\.\d{1,2})?$ 且 ^\d{1,3}(,\d{3})*(\.\d{1,2})?$ |