1.RegExp构造函数
es5写法:
var regex = new RegExp('xyz', 'i'); // 等价于 var regex = /xyz/i; var regex = new RegExp(/xyz/i); // 等价于 var regex = /xyz/i;
es6写法:
var regex = new RegExp(/xyz/, 'i');
2.字符串的正则方法
字符串对象共有 4 个方法,可以使用正则表达式:match()
、replace()
、search()
和split()。
ES6 将这 4 个方法,在语言内部全部调用RegExp
的实例方法,从而做到所有与正则相关的方法,全都定义在RegExp
对象上。
String.prototype.match 调用 RegExp.prototype[Symbol.match]
String.prototype.replace 调用 RegExp.prototype[Symbol.replace]
String.prototype.search 调用 RegExp.prototype[Symbol.search]
String.prototype.split 调用 RegExp.prototype[Symbol.split]
3.后行断言
es5先行断言:
先行断言:x(?=y)(x只有在y前面匹配)
/\d+(?=%)/.exec('100% of US presidents have been male') // ["100"] 先行否定断言:/x(?!y)/(x只有不在y前面才能匹配) /\d+(?!%)/.exec('that’s all 44 of them') // ["44"]
es6后行断言:
后行断言:/(?<=y)x/ 只匹配美元符号之后的数字,要写成/(?<=\$)\d+/
后行否定断言:/(?<!y)x/ 比如,只匹配不在美元符号后面的数字,要写成/(?<!\$)\d+/
。
/(?<=\$)\d+/.exec('Benjamin Franklin is on the $100 bill') // ["100"] /(?<!\$)\d+/.exec('it’s is worth about €90') // ["90"]
下面的例子是使用后行断言进行字符串替换。
const reg= /(?<=\$)foo/g; '$foo %foo foo'.replace(reg, 'bar'); // '$bar %foo foo'
上面代码中,只有在美元符号后面的foo
才会被替换。
4.flags属性
ES6 为正则表达式新增了flags
属性,会返回正则表达式的修饰符。
// ES5 的 source 属性 // 返回正则表达式的正文 /abc/ig.source // "abc" // ES6 的 flags 属性 // 返回正则表达式的修饰符 /abc/ig.flags // 'gi'
5.sticky属性
与y
修饰符相匹配,ES6 的正则对象多了sticky
属性,表示是否设置了y
修饰符。
var r = /hello\d/y; r.sticky // true
6.y修饰符
叫做“粘连”(sticky)修饰符。y
修饰符的作用与g
修饰符类似,也是全局匹配,后一次匹配都从上一次匹配成功的下一个位置开始。不同之处在于,g
修饰符只要剩余位置中存在匹配就可,而y
修饰符确保匹配必须从剩余的第一个位置开始,这也就是“粘连”的涵义。
var s = 'aaa_aa_a';
var r1 = /a+/g;
var r2 = /a+/y;
r1.exec(s) // ["aaa"]
r2.exec(s) // ["aaa"]
r1.exec(s) // ["aa"]
r2.exec(s) // null //因为第二次匹配时,s变量有_。所以匹配不到。直接是null。
r1.exec(s) // ["a"]
r2.exec(s) // null
上面代码说明g修饰符只要剩余位置存在匹配即可。而y修饰符必须确保匹配是从剩余的第一个位置开始。
var s = 'aaa_aa_a';
var r = /a+_/y;
r.exec(s) // ["aaa_"]
r.exec(s) // ["aa_"]
修改过后y修饰符也能返回结果。
2.lastIndex
属性
const REGEX = /a/g; // 指定从2号位置(y)开始匹配 REGEX.lastIndex = 2; // 匹配成功 const match = REGEX.exec('xaya'); // 在3号位置匹配成功 match.index // 3 // 下一次匹配从4号位开始 REGEX.lastIndex // 4 // 4号位开始匹配失败 REGEX.exec('xaya') // null
上面代码中,lastIndex
属性指定每次搜索的开始位置,g
修饰符从这个位置开始向后搜索,直到发现匹配为止。
y
修饰符同样遵守lastIndex
属性,但是要求必须在lastIndex
指定的位置发现匹配。
const REGEX = /a/y; // 指定从2号位置开始匹配 REGEX.lastIndex = 2; // 不是粘连,匹配失败 REGEX.exec('xaya') // null // 指定从3号位置开始匹配 REGEX.lastIndex = 3; // 3号位置是粘连,匹配成功 const match = REGEX.exec('xaya'); match.index // 3 REGEX.lastIndex // 4
实际上,y
修饰符号隐含了头部匹配的标志^
。
var reg = /b/y; var ret = reg.exec('baba') console.log(ret.index)//0 var reg = /b/y; var ret = reg.exec('aba') console.log(ret.index)//null
下面是字符串对象的replace
方法的例子。
g和y连用
const REGEX = /a/gy; 'aaxa'.replace(REGEX, '-') // '--xa'
单纯是g
const REGEX = /a/g; 'aaxa'.replace(REGEX, '-') // '--x-'
单纯是y
const REGEX = /a/y; 'aaxa'.replace(REGEX, '-') // '-axa'
单单一个y
修饰符对match
方法,只能返回第一个匹配,必须与g
修饰符联用,才能返回所有匹配。
'a1a2a3'.match(/a\d/y) // ["a1"] 'a1a2a3'.match(/a\d/gy) // ["a1", "a2", "a3"]
7.u修饰符
1.ES6 对正则表达式添加了u
修饰符,含义为“Unicode 模式”,用来正确处理大于\uFFFF
的 Unicode 字符。也就是说,会正确处理四个字节的 UTF-16 编码。
/^\uD83D/u.test('\uD83D\uDC2A') // false /^\uD83D/.test('\uD83D\uDC2A') // true
一旦加上u
修饰符号,就会修改下面这些正则表达式的行为。
(1)点字符
点(.
)字符在正则表达式中,含义是除了换行符以外的任意单个字符。对于码点大于0xFFFF
的 Unicode 字符,点字符不能识别,必须加上u
修饰符。
var s = '?';
/^.$/.test(s) // false
/^.$/u.test(s) // true
上面代码表示,如果不添加u
修饰符,正则表达式就会认为字符串为两个字符,从而匹配失败。
(2)Unicode 字符表示法
ES6 新增了使用大括号表示 Unicode 字符,这种表示法在正则表达式中必须加上u
修饰符,才能识别当中的大括号,否则会被解读为量词。
/\u{61}/.test('a') // false
/\u{61}/u.test('a') // true
/\u{20BB7}/u.test('?') // true
上面代码表示,如果不加u
修饰符,正则表达式无法识别\u{61}
这种表示法,只会认为这匹配 61 个连续的u
(3)量词
使用u
修饰符后,所有量词都会正确识别码点大于0xFFFF
的 Unicode 字符。
/a{2}/.test('aa') // true /a{2}/u.test('aa') // true /?{2}/.test('??') // false /?{2}/u.test('??') // true
(4)预定义模式
u
修饰符也影响到预定义模式,能否正确识别码点大于0xFFFF
的 Unicode 字符。
/^\S$/.test('?') // false
/^\S$/u.test('?') // true
上面代码的\S
是预定义模式,匹配所有非空白字符。只有加了u
修饰符,它才能正确匹配码点大于0xFFFF
的 Unicode 字符。
利用这一点,可以写出一个正确返回字符串长度的函数。
function codePointLength(text) {
var result = text.match(/[\s\S]/gu);
return result ? result.length : 0;
}
var s = '??';
s.length // 4
codePointLength(s) // 2
(5)i 修饰符
有些 Unicode 字符的编码不同,但是字型很相近,比如,\u004B
与\u212A
都是大写的K
。
/[a-z]/i.test('\u212A') // false /[a-z]/iu.test('\u212A') // true
上面代码中,不加u
修饰符,就无法识别非规范的K
字符。
8.字符串的正则方法
1.replace: 方法用于在字符串中用一些字符替换另一些字符,或替换一个与正则表达式匹配的子串。
语法:
stringObject.replace(regexp/substr,replacement)
egexp/substr
必需。规定子字符串或要替换的模式的 RegExp 对象。
请注意,如果该值是一个字符串,则将它作为要检索的直接量文本模式,而不是首先被转换为 RegExp 对象。
replacement 必需。一个字符串值。规定了替换文本或生成替换文本的函数。
返回值
一个新的字符串,是用 replacement 替换了 regexp 的第一次匹配或所有匹配之后得到的。
例子 1
在本例中,我们将使用 "W3School" 替换字符串中的 "Microsoft":
<script type="text/javascript">
var str="Visit Microsoft!"
document.write(str.replace(/Microsoft/, "W3School"))//Visit W3School!
</script>
例子 2
在本例中,我们将执行一次全局替换,每当 "Microsoft" 被找到,它就被替换为 "W3School":
<script type="text/javascript">
var str="Welcome to Microsoft! "
str=str + "We are proud to announce that Microsoft has "
str=str + "one of the largest Web Developers sites in the world."
document.write(str.replace(/Microsoft/g, "W3School"))
</script>
输出:
Welcome to W3School! We are proud to announce that W3School
has one of the largest Web Developers sites in the world.
例子 3
您可以使用本例提供的代码来确保匹配字符串大写字符的正确:
text = "javascript Tutorial";
text.replace(/javascript/i, "JavaScript");
2.match():检索指定的值,或找到一个或多个正则表达式的匹配。
语法:
stringObject.match(searchvalue)
stringObject.match(regexp)
searchvalue 必需。规定要检索的字符串值。
regexp 必需。规定要匹配的模式的 RegExp 对象。如果该参数不是 RegExp 对象,则需要首先把它传递给 RegExp 构造函数,将其转换为 RegExp 对象。
返回值
存放匹配结果的数组。该数组的内容依赖于 regexp 是否具有全局标志 g。
如果regexp没有全局g则匹配一次,反之全局匹配。如果没有找到任何匹配则返回null。
例1:
<script type="text/javascript">
var str="Hello world!"
document.write(str.match("world") + "<br />")
document.write(str.match("World") + "<br />")//大写的w
document.write(str.match("worlld") + "<br />")//多了一个l
document.write(str.match("world!"))
</script>
输出:
world
null
null
world!
例子 2
在本例中,我们将使用全局匹配的正则表达式来检索字符串中的所有数字:
<script type="text/javascript">
var str="1 plus 2 equal 3"
document.write(str.match(/\d+/g))
</script>
输出
1,2,3
例子 5
在本例中,我们将把所有的花引号替换为直引号:
name = '"a", "b"';
name.replace(/"([^"]*)"/g, "'$1'");
例子 6
在本例中,我们将把字符串中所有单词的首字母都转换为大写:
var name = 'aaa bbb ccc';
uw=name.replace(/\b\w+\b/g, function(word){
return word.substring(0,1).toUpperCase()+word.substring(1);}
);
3.search():用于检索字符串中指定的子字符串,或检索与正则表达式相匹配的子字符串。
语法
stringObject.search(regexp)
regexp
该参数可以是需要在 stringObject 中检索的子串,也可以是需要检索的 RegExp 对象。
注释:要执行忽略大小写的检索,请追加标志 i。
返回值
stringObject 中第一个与 regexp 相匹配的子串的起始位置。
注释:如果没有找到任何匹配的子串,则返回 -1。
说明
search() 方法不执行全局匹配,它将忽略标志 g。它同时忽略 regexp 的 lastIndex 属性,并且总是从字符串的开始进行检索,这意味着它总是返回 stringObject 的第一个匹配的位置。
例子 1
在本例中,我们将检索 "W3School":
<script type="text/javascript">
var str="Visit W3School!"
document.write(str.search(/W3School/))//6
</script>
在下面的例子中,无法检索到 w3school(因为 search() 对大小写敏感)。
<script type="text/javascript">
var str="Visit W3School!"
document.write(str.search(/w3school/))//-1
</script>
忽略大小写的检索
<script type="text/javascript">
var str="Visit W3School!"
document.write(str.search(/w3school/i))//6
</script>
4.split():用于把一个字符串分割成字符串数组。
语法
stringObject.split(separator,howmany)
separator 必需。字符串或正则表达式,从该参数指定的地方分割 stringObject。
howmany 可选。该参数可指定返回的数组的最大长度。如果设置了该参数,返回的子串不会多于这个参数指定的数组。如果没有设置该参数,整个字符串都会被分割,不考虑它的长度。
返回值
一个字符串数组。该数组是通过在 separator 指定的边界处将字符串 stringObject 分割成子串创建的。返回的数组中的字串不包括 separator 自身。
但是,如果 separator 是包含子表达式的正则表达式,那么返回的数组中包括与这些子表达式匹配的字串(但不包括与整个正则表达式匹配的文本)。
提示和注释
注释:如果把空字符串 ("") 用作 separator,那么 stringObject 中的每个字符之间都会被分割。
注释:String.split() 执行的操作与 Array.join 执行的操作是相反的。
<script type="text/javascript"> var str="How are you doing today?" document.write(str.split(" ") + "<br />")//直接使用“ ”;
document.write(str.split(/\s+/g) + "<br />")//使用正则表达式用空格空开。(这两个的结果是一样的)
document.write(str.split("") + "<br />")
document.write(str.split(" ",3)) //第三个空格前的内容
</script>
How,are,you,doing,today?
H,o,w, ,a,r,e, ,y,o,u, ,d,o,i,n,g, ,t,o,d,a,y,?
How,are,you
在本例中,我们将分割结构更为复杂的字符串:
var num = “2:3:4:5”';
var str "a|b|c";
num.split(":") //将返回["2", "3", "4", "5"]
str.split("|") //将返回["", "a", "b", "c"]
例子 3
使用下面的代码,可以把句子分割成单词:
var words = sentence.split(' ')
或者使用正则表达式作为 separator:
var words = sentence.split(/\s+/)
例子 4
如果您希望把单词分割为字母,或者把字符串分割为字符,可使用下面的代码:
"hello".split("") //可返回 ["h", "e", "l", "l", "o"]
若只需要返回一部分字符,请使用 howmany 参数:
"hello".split("", 3) //可返回 ["h", "e", "l"]