正则表达式本身就是一种语言,这在其它语言是通用的。
正则表达式(regular expression)描述了一种字符串匹配的模式,可以用来检查一个串是否含有某种子串、将匹配的子串做替换或者从某个串中取出符合某个条件的子串等。
创建正则对象
要使用正则表达式,必须要在程序创建正则对象 。我们需要得到一个RegExp类的实例。
① 直接量语法创建(隐式创建)
正则表达式直接量定义为包含在一对斜杠(/
)之间的字符。
var reg = /匹配模式/匹配标志;
② 构造函数创建
通过 RegExp() 构造函数可以实现动态创建正则表达式。RegExp() 的第二个参数是可选的。
var reg = new RegExp( " 匹配模式 " , ' 匹配标志 ' );
正则表达式字符
直接量字符
正则表达式中所有字母和数字都是按照字面含义进行匹配的,其他非字母的字符需要通过反斜杠(\)作为前缀进行转移,如 \n 匹配换行符。这些字符为直接量字符(literal characters)。这些字符都是精确匹配,每一个字符都只能匹配一个字符。
在正则表达式中,有一些标点符号具有特殊含义,他们是:^ $ . * + ? = ! : | \ / ( ) [ ] { } 如果需要在正则表达式中与这些直接量进行匹配,必须使用前缀 \ 。
字符类
如果不想匹配某一个特定的字符而是想匹配某一类字符,则需要使用字符类。
通过将直接量字符放入方括号内,可以组成字符类(character class)。一个字符类可以匹配它所包含任意 一个 字符。如 [abc] 可以匹配 a,b,c 中任意一个字符。
使用 ^ 作为方括号中第一个字符来定义否定字符集,它匹配所有不包含在方框括号内的字符。[^] 可以匹配任意字符。
字符类可以使用连字符来表示字符范围。比如匹配小写字母[a-z],匹配任何字母和数字可以用[a-zA-Z0-9]。
转义字符
一些常用的字符类,在 JavaScript 中有特殊的转义字符来表达它们。
字符 | 匹配 |
---|---|
[...] | 方括号内任意字符,方括号用于查找某个范围内的字符 |
[^...] | 不在方括号内任意字符,方括号用于查找某个范围内的字符 |
. |
除了换行符和其他 Unicode 行终止符之外的任意字符 |
\w | 等价于 [a-zA-Z0-9_] |
\W | 等价于 [^a-zA-Z0-9_] |
\s | 任何 Unicode 空白符 |
\S | 任何非 Unicode 空白符的字符 |
\d | 等价于 [0-9] |
\D | 等价于 [^0-9] |
\b | 匹配单词边界。通常用于查找位于单词的开头或结尾的匹配。 |
\B | 匹配非单词边界。匹配位置的上一个和下一个字符的类型是相同的:即必须同时是单词,或必须同时是非单词字符。字符串的开头和结尾处被视为非单词字符。 |
\0 | 查找 NULL 字符。 |
\n | 查找换行符。 |
\f | 查找换页符。 |
\r | 查找回车符。 |
\t | 查找制表符。 |
\v | 查找垂直制表符。 |
例如:
[abc] | 查找方括号之间的任何字符。 |
[^abc] | 查找任何不在方括号之间的字符。 |
[0-9] | 查找任何从 0 至 9 的数字。 |
[a-z] | 查找任何从小写 a 到小写 z 的字符。 |
[A-Z] | 查找任何从大写 A 到大写 Z 的字符。 |
var str = "Runoob Runoob"; document.write(str.replace(patt1,"AAA")); |
结果为:AAAoob AAAoob |
var str = "Rnoob Runoob"; var patt1 = /\Bnoob/; document.write(str.replace(patt1,"AAA")); |
结果为:RAAA Runoob |
量词
字符 | 含义 |
---|---|
n{X,Y} |
X 和 Y 为正整数。前面的模式 n 连续出现至少 X 次,至多 Y 次时匹配。 例如:/a{1,3}/ 匹配 "candy," 中的 "a","caandy," 中的两个 "a",匹配 "caaaaaaandy" 中的前面三个 "a"。 |
n{X,} |
X 是一个正整数。前面的模式 n 连续出现至少 X 次时匹配。 例如:/a{2,} 匹配 "caandy" 和 "caaaaaaandy." 中所有的 "a"。 |
n{X} |
匹配包含 X 个 n 的序列的字符串。 例如:/a{2}/ 匹配 "caandy," 中的两个 "a",且匹配 "caaandy." 中的前两个 "a"。 |
n? |
匹配任何包含零个或一个 n 的字符串。 例如,/e?le?/ 匹配 "angel" 中的 "el","angle" 中的 "le"。 |
n+ |
匹配任何包含至少一个 n 的字符串。 例如,/a+/ 匹配 "candy" 中的 "a","caaaaaaandy" 中所有的 "a"。 |
n* |
匹配任何包含零个或多个 n 的字符串。 例如,/bo*/ 匹配 "A ghost booooed" 中的 "boooo","A bird warbled" 中的 "b",但是不匹配 "A goat grunted"。 |
n$ |
匹配任何结尾为 n 的字符串。 例如,var str="Is this his"; var patt1=/is$/g; |
^n |
匹配任何开头为 n 的字符串。 例如,var str="Is this his"; var patt1=/^Is/g; |
?=n |
匹配任何其后紧接指定字符串 n 的字符串。 例如,对其后紧跟 "all" 的 "is" 进行全局搜索:var str="Is this all there is";var patt1=/is(?= all)/g; |
?!n | 匹配任何其后没有紧接指定字符串 n 的字符串。var str="Is this all there is";var patt1=/is(?! all)/gi; |
贪婪和非贪婪的重复
上面所有的重复都是“贪婪的”匹配,也就是匹配尽可能多的字符。如 /a+/ 匹配 'aaaa' 时,它会匹配 'aaaa' 。
如果想要尽可能少的匹配,只需要在重复的标记后加一个问号(?)即可。如 /a+?/ 匹配 'aaaa' 时,它会匹配 'a' 。
选择、分组和引用
选择
字符 | 用于分隔供选择的模式,匹配时会尝试从左到右匹配每一个分组,直到发现匹配项。如 /ab|bc|cd/ 可以匹配字符串'ab'、'bc' 和 'cd'。
// 一个分组中,可以有多个候选表达式,用|分隔: var reg = /I love (him|her|it)/; reg.test('I love him') // true reg.test('I love her') // true
捕获型分组
圆括号可以把单独的项组合成子表达式,以便可以像一个独立的单元用 |、*、+ 或者 ? 对单元内的项进行处理。
// 这里reg中的(/d{2})就表示一个分组,匹配两位数字。 var reg = /(\d{2})/ // 引用:被正则表达式匹配(捕获)到的字符串会被暂存起来。其中,由分组捕获的串会从1开始编 // 号,于是我们可以引用这些串,$1引用了第一个被捕获的串,$2是第二个,依次类推。分组可以通过$0-$9引 // 用,其中的$0只的是匹配的整个结果。比如我们想将日期12.21/2012改为2012-12-21: var reg = /(\d{2}).(\d{2})\/(\d{4})/ var date = '12.21/2012' date = date.replace(reg, '$3-$1-$2') // date = 2012-12-21 // 反向引用 // 正则表达式里也能进行引用,这称为反向引用: var reg = /(\w{3}) is \1/ reg.test('kid is kid') // true reg.test('kid is dik') // false // \1引用了第一个被分组所捕获的串,换言之,表达式是动态决定的。
非捕获型分组
有时候,我们只是想分个组,而没有捕获的需求,则可以使用非捕获型分组,语法为左括号后紧跟" ?: "
// 正向前瞻型分组: var reg = /kid is a (?=doubi)/ reg.test('kid is a doubi') // true // kid is a 后面跟着什么?如果是doubi才能匹配成功。 reg.test('kid is a shabi') // false // 负向前瞻型分组: var reg = /kid is a (?!doubi)/ reg.test('kid is a doubi') // false reg.test('kid is a shabi') // true // 负向前瞻则刚好相反,不是doubi才能匹配成功。
指定匹配位置(锚元素)
有一些正则表达式的元素不用来匹配实际的字符,而是匹配指定的位置。我们称这些元素为正则表达式的锚。
正则表达式中的锚字符包括:
- ^ 用来匹配字符串的开始,多行检索时匹配一行的开头。
- $ 用来匹配字符串的结束,多行检索时匹配一行的结尾。
- \b 用来匹配单词的边界,就是 \w 和 \W 之间的位置,或者 \w 和字符串的开头或结尾之间的位置。
- \B 匹配非单词边界的位置。
- 例: /\bJava\b/ 可以匹配 Java 却不匹配 JavaScript。
任意正则表达式都可以作为锚点条件。
先行断言
(?=pattern) 它表示一个位置,该位置之后的字符能匹配 pattern 。如 /\d+(?=%)/ 匹配字符串 '100%' 中的 '100' 但是不匹配 '100。'
负向先行断言
(?!pattern) 它表示一个位置,该位置之后的字符不能匹配 pattern 。
后行断言
(?<=pattern) 它表示一个位置,该位置之前的字符能匹配 pattern 。例,/(?<=\$)\d+/ 匹配 '$100' 但是不匹配 '¥100'。
负向后行断言
(?<!pattern) 它表示一个位置,该位置之前的字符能不匹配 pattern。
修饰符
在正则表达式的第二条斜线之后,可以指定一个或多个修饰符,/pattern/g。
常用修饰符:
- i 执行不区分大小写的匹配。
- g 全局匹配。
- m 多行匹配模式。
- y “粘连”(sticky)修饰符。y修饰符的作用与g修饰符类似,也是全局匹配,后一次匹配都从上一次匹配成功的下一个位置开始。不同之处在于,g修饰符只要剩余位置中存在匹配就可,而y修饰符确保匹配必须从剩余的第一个位置开始,这也就是“粘连”的涵义。
- s 表示点(.)可以表示任意字符,不设置的话,四个字节的 UTF-16 字符和行终止符不能用 . 表示。
- u 开启 “Unicode 模式”,用来正确处理大于 \uFFFF 的 Unicode 字符。也就是说,会正确处理四个字节的 UTF-16 编码。
通过 RegExp.prototype.flags 可以获得正则修饰符的字符串。/pattern/ig.flags 返回 "gi"。
JavaScript search() 方法
定义和用法
search() 方法用于检索字符串中指定的子字符串,或检索与正则表达式相匹配的子字符串。
如果没有找到任何匹配的子串,则返回 -1。
语法
string.search(searchvalue)
参数值
参数 | 描述 |
---|---|
searchvalue | 必须。查找的字符串或者正则表达式。 |
返回值
类型 | 描述 |
---|---|
Number | 与指定查找的字符串或者正则表达式相匹配的 String 对象起始位置。 |
例如
var str="Visit Runoob!"; var n=str.search("Runoob"); //6
JavaScript replace() 方法
定义和用法
replace() 方法用于在字符串中用一些字符替换另一些字符,或替换一个与正则表达式匹配的子串。
语法
string.replace(searchvalue,newvalue)
参数值
参数 | 描述 |
---|---|
searchvalue | 必须。规定子字符串或要替换的模式的 RegExp 对象。 请注意,如果该值是一个字符串,则将它作为要检索的直接量文本模式,而不是首先被转换为 RegExp 对象。 |
newvalue | 必需。一个字符串值。规定了替换文本或生成替换文本的函数。 |
返回值
类型 | 描述 |
---|---|
String | 一个新的字符串,是用 replacement 替换了 regexp 的第一次匹配或所有匹配之后得到的。 |
例如
var str="Visit Microsoft! Visit Microsoft!"; var n=str.replace("Microsoft","Runoob"); //Visit Runoob!Visit Microsoft!
JavaScript match() 方法
定义和用法
match() 方法可在字符串内检索指定的值,或找到一个或多个正则表达式的匹配。
语法
string.match(regexp)
参数值
参数 | 描述 |
---|---|
regexp | 必需。规定要匹配的模式的 RegExp 对象。如果该参数不是 RegExp 对象,则需要首先把它传递给 RegExp 构造函数,将其转换为 RegExp 对象。 |
返回值
类型 | 描述 |
---|---|
Array | 存放匹配结果的数组。该数组的内容依赖于 regexp 是否具有全局标志 g。 如果没找到匹配结果返回 null 。 |
例如
var str="The rain in SPAIN stays mainly in the plain"; var n=str.match(/ain/g); //ain,ain,ain
JavaScript split() 方法
定义和用法
split() 方法用于把一个字符串分割成字符串数组。
提示: 如果把空字符串 ("") 用作 separator,那么 stringObject 中的每个字符之间都会被分割。
注意: split() 方法不改变原始字符串。
语法
string.split(separator,limit)
参数值
参数 | 描述 |
---|---|
separator | 可选。字符串或正则表达式,从该参数指定的地方分割 string Object。 |
limit | 可选。该参数可指定返回的数组的最大长度。如果设置了该参数,返回的子串不会多于这个参数指定的数组。如果没有设置该参数,整个字符串都会被分割,不考虑它的长度。 |
返回值
类型 | 描述 |
---|---|
Array | 一个字符串数组。该数组是通过在 separator 指定的边界处将字符串 string Object 分割成子串创建的。返回的数组中的字串不包括 separator 自身。 |
例如
var str="How are you doing today?"; var n=str.split(" "); //How,are,you,doing,today? var str="张三;李四,王五|赵六"; var n=str.split(/[;\|,]/,4); // ["张三", "李四", "王五", "赵六"]
RegExp正则
RegExp 对象属性
属性 | 描述 |
---|---|
constructor | 返回一个函数,该函数是一个创建 RegExp 对象的原型。 |
global | 判断是否设置了 "g" 修饰符 |
ignoreCase | 判断是否设置了 "i" 修饰符 |
lastIndex | 用于规定下次匹配的起始位置 |
multiline | 判断是否设置了 "m" 修饰符 |
source | 返回正则表达式的匹配模式 |
RegExp 对象方法
方法 | 描述 |
---|---|
exec | 检索字符串中指定的值。返回找到的值,并确定其位置。 |
test | 检索字符串中指定的值。返回 true 或 false。 |
toString | 返回正则表达式的字符串。 |
常用正则表达式
// 整数最多2位,小数最多3位 /^\d{1,2}(\.\d{1,3})?$/ // 包含两位小数的百分比 /^(((\d|[1-9]\d)(\.\d{1,2})?)|100|100.0|100.00)$/ // 最多输入8位,如果还输入小数则最多保留后两位,并且大于0 /(^[0-9]{1,8}$)|(^[0-9]{1,10}[\.][0-9]{1,2}$)/ // 最多输入10位,如果还输入小数则最多保留后两位,并且大于0,允许输入正负号 /(^(\-|\+)?[0-9]{1,12}$)|(^[0-9]{1,10}[\.]{1}[0-9]{1,2}$)/ // 固定电话 /^(\(\d{3,4}\)|\d{3,4}-|\s)?\d{7,14}$/
利用正则表达式实现输入限制
<a-input @change="e =>validateFields_code(e, 5)" /> // 限制仅允许输入数字及小数点后两位,不限制位数 validateFields_money (e) { var value = e.target.value.replace(/^\D*(\d*(?:\.\d{0,2})?).*$/g, '$1') e.target.value = value return value } // 限制仅允许输入数字及小数点后两位,只限制整数位数 validateFields_money_matchlength (e, len) { var value = e.target.value.replace(/^\D*(\d*(?:\.\d{0,2})?).*$/g, '$1') if (value.indexOf('.') != -1) { var strs = value.split('.') var numStr = strs[0] if (numStr.length > len) { numStr = numStr.substring(0, len) } value = numStr + '.' + strs[1] } else if (value.length > len) { value = value.substring(0, len) } e.target.value = value return value } // 只允许输入整数 <a-input @change="validateFields_money" /> validateFields_num (e) { var value = e.target.value.replace(/^\D*(\d*(?:)?).*$/g, '$1') e.target.value = value return value } // 只允许输入字母和数字,并限制字数 <a-input @change="e =>validateFields_code(e, 5)" /> validateFields_code (e, length) { var value = e.target.value.replace(/[^a-zA-Z0-9]/gi, '') if (value.length > length) { value = value.substring(0, length) } e.target.value = value return value }, // 只允许输入字母数字汉字和指定的特殊字符 <a-input @change="validateFields_money" /> validateFields_input_str (e) { var value = e.target.value.replace(/[^a-zA-Z\d\u4e00-\u9fa5,。!?()]/g, '') e.target.value = value return value }