2.0 简单介绍
正則表達式是能够用来查找与给定模式匹配的文本的搜索模式。比如,在上一章中,我们在一个较长的字符串中查找子字符串Cookbook:
var testValue = "http://www.mamicode.com/This is the Cookbook‘s test string";
var subsValue = "http://www.mamicode.com/Cookbook";
var iValue = http://www.mamicode.com/testValue.indexOf(subsValue); //返回值12。即子字符串的索引
这段代码有效。由于我们要查找一个严格的匹配。可是。假设想要一个更加通用的搜索,该怎么办呢?比如,我想要在"Joe‘s Cooking Book" 或 "JavaScript Cookbook"这种字符串中搜索单词Cook和Book。
当要查找匹配一个模式的字符串,而不是一个详细的字符串的时候。我们须要使用正則表達式。我们也能够尝试用String函数来做到这点。可是。终于实际上使用正則表達式要更为简单,虽然语法和格式要稍微奇怪一点。而且不一定“用户友好”。
近期,我在查看从一个字符串提取RGB的代码,以便将颜色转换为十六进制的格式。
我试图仅仅是使用String.split函数。而且依据逗号来切割,可是,随后我必须去除掉圆括号和不相关的空白。
还有一个须要考虑的问题是。怎样能够确保值是十进制的格式呢?
我们可能找到的是:
rgb(100%, 0, 0)
rgb(255, 0, 0)
还有还有一个问题:一些浏览器将颜色(比如。一个背景颜色)返回为一个RGB值,而不是一个十六进制值。在构建一个一致的转换程序的时候,你须要两种形式都能处理。
最后,一组正則表達式使得我们可以解决这些问题。起初,这些看上去好像是鸡毛蒜皮的问题,可是,终于它们变得要复杂非常多。在流行的jQuery UI库的一个样例中,正則表達式用来匹配颜色值。这是一项复杂的任务,由于该颜色值可能呈现多种不同的格式,正如程序的这一部分所看到的:
//查找#a0b1c2
if (result = /#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-Z0-9]){2}/.exec(color)) {
return [parseInt(result[1], 16), parseInt(result[2], 16), parseInt(result[3], 16)];
}
//查找#fff
if (result = /#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(color)) {
return [parseInt(result[1]+result[1],16), parseInt(result[2]+result[2],16), parseInt(result[3]+result[3],16)];
}
//在Safari3中查找rgba(0, 0, 0, 0) == transparent
if (result = /rgba\(0, 0, 0, 0\)/.exec(color)) {
return colors[‘transparent‘];
}
//否则。我们非常可能处理一个命令的颜色
return colors[$.trim(color).toLowerCase()];
虽然这个正則表達式似乎有些复杂,它们实际上仅仅只是是描写叙述模式的一种方式。在JavaScript中,正則表達式通过RegExp对象来管理。
RegExp直接量
与我们在第一章中学习的String一样。RegExp也能够是一个直接量和一个对象。要创建一个RegExp直接量,使用例如以下的语法:
var re = /regular expression/;
正則表達式模式包括在開始的斜杠和结束的斜杠之间。注意,这个模式不是一个字符串,你不想使用单引號或双引號括起模式。除非引號本身也是要匹配的模式的一部分。
正則表達式是由字符串组成的。要么仅仅是字符。要么是与特殊的组合,后者提供更加复杂的匹配。
比如,以下是匹配包括单词Shelley和单词Powers的一个字符串的模式的正則表達式,这两个单词依次出现,之间有一个或多个空白字符隔开:
var re = /Shelley\s+Powers/;
正則表達式模式包括在開始的斜杠和结束的斜杠之间。
注意,这个模式不是一个字符串,你不想使用单引號或双引號括起模式,除非引號本身也是要匹配的模式的一部分。
正則表達式是由字符串组成的。要么仅仅是字符,要么是与特殊字符的组合,后者提供更加复杂的匹配。比如,以下是匹配包括单词Shelley和单词Powers的一个字符串的模式的正則表達式。这两个单词一次出现,之间有一个或多个空白字符隔开:
var re = /Shelley\s+Powers/;
这个演示样例中的特殊字符是反斜杠字符(\)。它有两个目的:要么与一个常规字符一起使用,表明该字符是一个特殊字符:要么与一个特殊字符一起使用,比如,加号(+),表明该字符应该当作直接量对待。在这个样例中。反斜杠与"s"一起使用,将该字母转换为一个特殊字符,表示空白字符,比如一个空格、制表符、换行或换页。
\s特殊字符后面跟着一个加号,即\s+,当中+是一个标志。表示匹配之前的字符(在这个样例中。是一个空白字符)一次或多次。这个正則表達式将对例如以下形式有效:
Shelley Powers
它也会对以下的形式有效:
Shelley Powers
但它对以下的形式无效:
ShelleyPowers
Shelley和Powers之间有多少空白是无关紧要的,由于使用了\s+。
然而,使用加号则至少须要一个空白符。
如果如果要都对这三种都能匹配。正則表達式改动为例如以下格式:
var re = /Shelley\s*Powers/;
表2-1给出了JavaScript应用程序中最经常使用的特殊字符。
表2-1:正則表達式特殊字符
字符 |
匹配 |
演示样例 |
^ |
匹配输入的開始 |
/^This/匹配"This is..." |
$ |
匹配输入的结束 |
/end$/匹配"This is the end" |
* |
匹配0次或多次 |
/se*/匹配"seeee",也匹配"se" |
? |
匹配0次或1次 |
/ap?/匹配"apple"和"and" |
+ |
匹配一次或多次 |
/ap+/匹配"apple"。但不匹配"and" |
{n} |
严格匹配n次 |
/ap{2}/匹配"apple"。但不匹配"apie" |
{n,} |
匹配n次或多于n次 |
/ap{2,}/匹配"apple"和"appple"中的全部p。可是不匹配"apie" |
{n,m} |
匹配至少n次,至多m次 |
/ap{2,4}/匹配"apppppple"中的4个"p" |
. |
除了换行以外的不论什么字符 |
/a.e/匹配"ape"和axe" |
[...] |
方括号里的不论什么字符 |
/a[px]e/匹配"ape"和"axe",但不匹配"ale" |
[^...] |
方括号里字符以外的不论什么字符 |
/a[^px]/ "ale"。可是不匹配"axe"或"ape" |
\b |
匹配边界上的单词 |
/\bno/匹配 "nono"中的第一个"no" |
\B |
匹配非边界上的单词 |
/\Bno/匹配"nono"中的第二个"no" |
\d |
从0到9的数字 |
/\d{3}/匹配 "Now in 123"中的"123" |
\D |
不论什么非数字的字符 |
/\D{2,4}/ 匹配"Now in 123"中的"Now " |
\w |
匹配单词字符(字母、数字、下划线) |
/\w/匹配javascript中的"j" |
\W |
匹配不论什么非单词的字符(非字母、数字、下划线) |
/\W/匹配"100%"中的"%" |
\n |
匹配一个换行 |
|
\s |
一个单个的空白字符 |
|
\S |
一个单个的非空白字符 |
|
\t |
一个制表符 |
|
(x) |
捕获圆括号 |
记住匹配的字符 |
作为对象的RegExp
RegExp是一个JavaScript对象,也是一个直接量,因此。它也能够使用一个构造函数来创建,例如以下所看到的:
var re = new RegExp("Shelley\s+Powers");
何时使用这两种形式呢?RegExp直接量在脚本执行时才编译,因此,当你知道表达式不会改动的时候,使用一个RegExp直接量。一个编译过的版本号会更高效。当要改动表达式或构建表达式或提供给执行时的时候,就使用构造函数。
与其它的JavaScript对象一样,RegExp也有一些属性和方法。本章中将会介绍当中最常见的几个。
2.1 測试一个子字符串是否存在
问题:想要測试一个字符串中是否包括还有一个字符串。
解决方式
使用一个JavaScript正則表達式来定一个搜索模式,然后,依据要搜索的字符串来应用该模式,使用RegExp test方法。在例如以下的代码中。我想要匹配带有Cook和Book这两个单词的不论什么字符串。两个单词依照前后顺序出现:
var cookbookstring = [
"Joe‘s Cooking Book",
"Sam‘s Cookbook",
"JavaScript CookBook",
"JavaScript BookCook"
];
//搜索模式
var pattern = /Cook.*Book/;
for (var i = 0; i < cookbookstring.length; i++) {
alert(cookbookstring[i] + " " + pattern.test(cookbookstring[i]));
}
第一个字符串和第三个字符串有一个正确的匹配。而第二个字符串和第四个字符串则没有。
讨论
RegExp test方法接受两个參数:要測试的字符串和一个可选的修饰符。它对该字符串应用正則表達式。假设有一个匹配的话。返回true,假设没有匹配的话,返回false。
在这个样例中。模式是单词Cook出如今字符串的某处。而且单词Book出如今字符串中Cook之后的某处。两个单词之间能够有随意数目的字符。包含没有不论什么字符。正如模式中用两个正則表達式字符串所指定的那样:小数点(.)和星号(*)。
正則表達式中的小数点是一个特殊字符,它匹配换行符以外的不论什么字符。
在演示样例的模式中,小数点后面跟着星号,它表示匹配之前的字符0次或多次。组合到一起。它们产生一个模式,匹配不论什么字符0次或多次,除了换行符之外。
在这个演示样例中。第一个和第三个字符串匹配。由于它们都满足了Cook和Book之间能够有不论什么内容的要求。
第四个字符串不匹配,由于在字符串中,Book出如今了Cook的前面。第二个字符串也不匹配,由于book的第一个字母是小写的而不是大写的。而且该匹配模式是区分大写和小写的。
2.2 測试不区分大写和小写的子字符串匹配
问题:
你想要測试一个字符串是否包括于还有一个字符串之中,可是你并不在意两个字符串中的字符的大写和小写。
解决方式:
在创建正則表達式的时候,使用忽略大写和小写标志(i):
var cookbookString = [
"Joe‘s Cooking Book",
"Sam‘s Cookbook",
"JavaScript CookBook",
"JavaScript cookbook"
];
//搜索模式
var pattern = /Cook.*Book/i;
for (var i = 0; i < cookbookString.length; i++) {
alert(cookbookString[i] + " " + pattern.test(cookbookString[i], i));
}
全部4个字符串都匹配该模式。
讨论
该解决方式使用了一个正則表達式标志(i),来改动对模式匹配的限制。
在这个样例中,该标志去除了模式匹配必须依照大写和小写匹配的限制。使用这一标志,book的值和Book的值都将是匹配的。
还有几个正則表達式标志,參见表2-2。它们能够与RegExp直接量一起使用:
var pattern = /Cook.*Book/i; // ‘i‘是忽略标志
也能够在创建一个RegExp对象的时候,通过可选的第二个參数来使用它们:
var pattern = new RegExp("Cook.*Book", "i");
表2-2:正則表達式标志
标志 |
含义 |
g |
全局匹配:在整个字符串中匹配,而不是在第一次匹配之后停止 |
i |
忽略大写和小写 |
m |
对多行字符串中的每一行,应用行首和行末的特殊字符(各自是^和$) |
2.3 验证社会安全号码
问题:
你须要验证一个文本字符串是否是一个有效的美国社会安全号码(在美国,这是收税者用来找到我们的身份标识)。
解决方式:
使用String match方法和一个正則表達式来验证一个字符串是一个社会安全号码:
var ssn = document.getElementById("pattern").value;
var pattern = /^\d{3}-\d{2}-\d{4}$/;
if (ssn.match(pattern)) {
alert("OK");
} else {
alert("Not OK");
}
讨论:
美国社会安全号码是9位数字的一个组合,通常依次是3个数字、2个数字和4个数字。之间可能有连字符或者没有。
社会安全号码中的数字能够用数字特殊字符(\d)来匹配。
要查找一组数字,能够使用花括号把期待的数字的数目括起来。在这个样例中,前3个数字能够用\d{3}来匹配。
第二组数字能够使用相同的规则来确定。因为数字序列之间仅仅有一个连字符。能够不用不论什么特殊的字符来给定它。然而。假设字符串也可能有一个不带连字符的社会安全号码,你希望将该正則表達式模式改动为例如以下所看到的:
var pattern = /^\d{3}-?\d{2}-?\d{4}$/;
问号特殊字符(?)匹配其前面的字符0次或者仅1次,在这个样例中,这个字符就是连字符(-)。通过这一改动。例如以下的字符串将匹配:
444-55-3333
例如以下的也会匹配:
555335555
可是。以下的字符串不会匹配,它的连字符太多了:
555---60--4444
还有一个特点是,检查字符串是否包括社会安全号码(而且仅仅有社会安全号码)。输入開始特殊字符(^)用来表示社会安全号码从字符串的開始处開始,行末特殊字符($)用来表示该行以社会安全号码的末尾为结束。
因为仅仅是对验证字符串是一个有效格式的社会安全号码感兴趣。我们使用了String对象的match方法。我们还能够使用RegExp test方法,可是,两种方法差点儿相同,都能够接收。
还有其它的方法能够验证社会安全号码。可是较为复杂。是基于社会安全号码能够用空格取代连字符的原理。这就是为什么大多数Web网站要求依照3个不同的输入字段来提供一个社会安全号码,以避免出现各种变体。正則表達式不应该用来替代良好的表单设计。
此外,没有方法真正地验证给定的数字就是一个真实的社会安全号码。除非你拥有关于这个人的很多其它信息。而且有一个存储全部社会安全号码的数据库。使用正則表達式所可以做的,仅仅是验证数字的格式。
2.4 找到并突出显示一个模式的全部实例
问题:
想要在一个字符串中找到一个模式的全部实例
解决方式:
在一个循环中。使用RegExp exec方法和全局标志(g)。来找到一个模式的全部演示样例,比如,不论什么以t开头而且以e结尾、中间有随意多个字符的单词或其它文本:
var searchString = "Now is the time and this is the time and that is the time";
var pattern = /t\w*e/g;
var matchArray;
var str = "";
while ((matchArray = pattern.exec(searchString)) != null) {
str += "at " + matchArray.index + "we found" + matchArray[0] + "<br />";
}
document.getElementById("results").innerHTML = str;
讨论
RegExp exec方法运行该正則表達式,假设没有找到一个匹配。返回null,或者。假设找到一个匹配,返回带有信息的一个数组。返回的数组中所包括的,是实际匹配的值、在字符串中找到匹配的索引、不论什么带圆括号的子字符串匹配。以及最初的字符串。
index:定位匹配的索引
input:最初的输入字符串
[0]:或直接訪问数组匹配值
[1],...,[n]:带圆括号的子字符串匹配
在这个解决方式中。除了打印出匹配的值,还打印出找到匹配的位置的索引。
这一解决方式还使用了全局标志(g)。这触发了RegExp对象去保留每一次匹配的位置。而且从之前找到的匹配的后面開始搜索。当用于循环中的时候,我们能够找到模式匹配字符串的全部实例。在这个解决方式中,将有例如以下的输出:
at 7 we found the
at 11 we found time
at 28 we found the
at 32 we found time
at 49 we found the
at 53 we found time
让我们来看看应用全局搜索的本质。在演示样例2-1中。我们创建了一个Web页面,它带有一个textarea和一个输入文本框。分别用来获取一个搜索字符串和一个模式。
模式用来创建一个RegExp对象,随后将其应用于字符串。
构建了一个结果字符串。
当中包括了未匹配的文本和匹配的文本,仅仅只是匹配的文本用一个span元素包围起来,该元素一个CSS类用来突出显示该文本。
然后使用div元素的innerHTML,将结果字符串插入到该页面中。
演示样例2-1:使用exec和全局标志来查找并突出显示一个文本字符串中的全部匹配
<!doctype html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Searching for strings</title>
<style type="text/css">
#searchSubmit {
background-color: #ff0;
width: 200px;
text-align: center;
padding: 10px;
border:2px inset #ccc;
}
.found {
background-color: #ff0;
}
</style>
<script type="text/javascript">
//<![CDATA[
window.onload = function() {
document.getElementById("searchSubmit").onclick = doSearch;
}
function doSearch() {
//获取模式
var pattern = document.getElementById("pattern").value;
var re = new RegExp(pattern, "g");
//获取字符串
var searchString = document.getElementById("incoming").value;
var matchArray;
var resultString = "<pre>";
var first = 0;
var last = 0;
//找到每个匹配
while ((matchArray = re.exec(searchString)) != null) {
last = matchArray.index;
//获取全部匹配的字符串,将其连接起来
resultString += searchString.substring(first, last);
//使用class。加入匹配的字符串
resultString += "<spn class=‘found‘>" + matchArray[0] + "</span>";
first = re.lastIndex;
}
//完毕字符串
resultString += searchString.substring(first, searchString.length);
resultString += "</pre>";
//插入到页面
document.getElementById("searchResult").innerHTML = resultString;
}
//--><!]]>
</script>
</head>
<body>
<form id="textsearch">
<textarea id="incoming" cols="150" rows="10"></textarea>
<p>Search pattern: <input id="pattern" type="text" /></p>
</form>
<p id="searchSubmit">Search for pattern</p>
<div id="searchResult"></div>
</body>
</html>
图2-1显示了这个程序在William Wordsworth的诗歌 "The Kitten and the Falling Leaves"上的应用,在搜索了乳腺癌的模式之后:
竖杠(|)是一个条件測试。而且将依据竖杠左边或右边的值来匹配一个单词。因此,想leaf这种单词会匹配,想leave这种单词也会匹配,而leap这种单词不会匹配。
能够通过RegExp的lastIndex属性,来获取找到的最后一个索引。假设你想要把第一个匹配和最后一个匹配都记录下来,lastIndex属性非常方便。
2.5使用新字符串替换模式
问题:
想要用一个新的子字符串替换全部匹配的子字符串。
解决方式:
使用String对象的replace方法和一个正則表達式:
var searchString = "Now is the time, this is the time";
var re = /t\w{2}e/g;
var replacement = searchString.replace(re, "place");
alert(replacement); //字符串变成了"Now is the place, this is the place"
讨论:
在2.4节的演示样例2-1中,我们使用了RegExp全局标志(g),以记录正則表達式的每一次出现。
每次匹配都使用一个span元素和CSS来突出显示。
对于典型的查找替换行为,全局搜索也非常方便。
使用全局标志(g)和一个正則表達式,并结合String replace方法,将能够使用替换字符串来替代匹配文本的全部实例。
2.6 使用捕获圆括号交换一个字符串中单词
问题:
我们能够接受一个带有名称和姓氏的输入字符串。而且交换名称。以便让姓氏先出现。
解决方式
使用捕获圆括号和一个正則表達式在字符串中找到并记住两个名字,然后互换它们:
var name = "Abe Lincoln";
var re = /^(\w+)\s(\w+)$/;
var newname = name.replace(re, "$2, $1");
讨论
捕获圆括号使得我们不仅可以匹配字符串中的特定模式。并且稍后可以引用匹配的子字符串。
匹配的子字符串用数字来引用,从左到有,在String replace方法中使用 "$1"和"$2"来表示。
在这个解决方式中。正則表達式匹配两个单词,这两个单词用空格隔开。对这两个单词,都应用了捕获圆括号,因此。使用"$1"訪问名称,使用"$2"訪问姓氏。
捕获圆括号并不是是能够与String replace方法一起使用的唯一的特殊字符。表2-3给出了能够与正則表達式和replace一起使用的其它特殊字符。
表2-3:String.replace特殊模式
模式 |
用途 |
$$ |
同意替换中有一个直接量-美元符号($) |
$& |
插入匹配的子字符串 |
$` |
在匹配之前插入字符串的一部分 |
$’ |
在匹配之后插入字符串的一部分 |
$n |
插入使用RegExp的第n次捕获圆括号的值 |
该表的第二条“插入匹配的子字符串”。能够用来提供2.4节中的演示样例2-1的一个简化版本号。
该演示样例找到匹配的子字符串,而且提供标记和CSS来样式化它。它使用一个循环来找到并替换全部的条目。可是在演示样例2-2中。我们将使用String replace方法和匹配的字符串的特殊模式($&):
演示样例2-2:使用String.replace和特殊模式在字符串中查找文本并突出显示
<!doctype html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Searching for strings</title>
<style>
#searchSubmit {
background-color: #ff0;
width: 200px;
text-align: center;
padding: 10px;
border: 2px insert #ccc;
}
.found {
background-color: #ff0;
}
</style>
<script>
//<![CDATA[
window.onload = function() {
document.getElementById("searchSubmit").onclick = doSearch;
}
function doSearch() {
//获取模式
var pattern = document.getElementById("pattern").value;
var re = new RegExp(pattern, "g");
//获取字符串
var searchString = document.getElementById("incoming").value;
//替换
var resultString = searchString.replace(re, "<span class=‘found‘>$&</span>");
//插入到页面
document.getElementById("searchResult").innerHTML = resultString;
}
//--><!]]>
</script>
</head>
<body>
<form id="textsearch">
<textarea id="incoming" cols="100" rows="10">
</textarea>
<p>
Search pattern: <input id="pattern" type="text" />
</p>
</form>
<p id="searchSubmit">Search for pattern</p>
<div id="searchResult"></div>
</body>
</html>
这是一个简单的替代。如图2-2所看到的,这一技术不会严格保留最初的字符串的全部方面。
在演示样例2-2中。换行没有保留,可是在演示样例2-1中,它们保留了。
当你使用RegExp exec方法的时候。还能够通过RegExp对象来訪问捕获的文本。如今,让我们回到第2.6节的解决方式的代码,但这一次使用RegExp的exec方法:
var name = "Shelley Powers";
var re = /^(\w+)\s(\w+)$/;
var result = re.exec(name);
var newname = result[2] + ", " + result[1];
假设想要訪问捕获圆括号值。这样的方法非常方便,可是,在字符串替换中不一定要使用它们。要查看使用捕获圆括号的还有一个演示样例,1.7节展示了訪问例如以下句子的列表项的几种方法。用到了String split方法:
var sentence = "This is one sentence. This is a sentence with a list of items: cherries, oranges, apples, bananas.";
还有一种方法例如以下所看到的,使用捕获圆括号和RegExp exec方法:
var re = /:(.*)\./;
var result = re.exec(sentence);
var list = result[1]; // cherries, oranges, apples, bananas
2.7 使用正則表達式来去除空白
问题
在通过一个Ajax调用把一个字符串发送给server之前。我们想要去除字符串開始处和结尾处的空白。
解决方式
在新的ECMAScript 5规范之前。我们须要使用一个正則表達式来去除字符串開始处和结尾处的空白:
var testString = " this is the string ";
//去除开头处的空白
testString = testString.replace(/^\s+/, "");
//去除结尾处的空白testString = testString.replace(/\s+$/, "");
从ECMAScript 5開始。String对象有了一个trim方法:
var testString = " this is the string ";
testString = testString.trim(); //空白去除掉了
讨论
从元素获取的字符串值有时候在实际的表单值的前面和后面都会有空白。通常,我们想要发送没有多余空白的字符串。因此须要使用一个正則表達式来修正字符串。
有了ECMAScript 5之后,如今又有了一个String trim方法。然而。ECMAScript 5还没有广泛使用,因此,我们须要检查是否存在trim方法,假设不存在的话。使用旧的正則表達式是一种安全保险的方法。
此外,ECMAScript 5中没有左去除和右去除,虽然在Firefox这种一些浏览器中,有这些方法的非标准版本号。因此。假设仅仅是想要左去除或右去除。我们须要创建自己的函数:
function leftTrim(str) {
return str.replace(/^\s+/, "");
}
function rightTrim(str) {
return str.replace(/\s+$/, "");
}
2.8 使用命名实体来替代HTML标签
问题
你想要把演示样例标记粘贴到一个Web页面中,而且转义该标记,打印出尖括号而不是进行内容解析。
解决方式
使用正則表達式把尖括号(<>)转换为命名实体:<和>。
var pieceOfHtml = "<p>This is a <span>paragraph</span></p>";
pieceOfHtml = pieceOfHtml.replace(/</g, "<");
pieceOfHtml = pieceOfHtml.replace(>/g, ">");
document.getElementById("searchResult").innerHTML = pieceOfHtml;
讨论
将标记例子粘贴到还有一个Web页面中,这是非经常见的。要让当中的文本打印出来,而不是让浏览器解析它,唯一的方法是把全部的尖括号转换为其等价的命名实体。
使用正則表達式的话,这个过程会非常easy。就像在这个解决方式中所展示的那样,使用正則表達式全局标志(g)和String replace方法。
2.9 搜索特殊字符
问题
我们要搜索数字和字母、以及不论什么非数字或其它字符的内容,可是须要搜索的内容之中的一个是特殊的正則表達式字符自身。
解决方式
使用反斜杠来转义模式匹配字符:
var re = /\\d/;
var pattern = "\\d{4}";
var pattern2 = pattern.replace(re, "\\D");
讨论
在这个解决方式中,创建了一个正則表達式,它等同于特殊字符\d。用来匹配不论什么数字。在须要搜索的字符串中,该模式自身是转义的。
随后,用来搜索不论什么数字的特殊字符\D。替代了数字特殊字符。
听起来有点令人费解,因此,我们用一个较长的应用程序来展示。
演示样例2-3展示了一个较小的应用程序,它首先在一个字符串中搜索4个数字的一个序列,而且用4个星号(****)替换它们。接下来。应用程序通过使用\D替代\d来改动搜索模式,然后对相同的字符串再次执行它。
演示样例2-3: 匹配正則表達式字符的正則表達式
<DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Replacement Insanity</title>
</head>
<script>
//<![CDATA[
window.onload = function() {
//查找 \d
var re = /\\d/;
var pattern = "\\d{4}";
var str = "I want 1111 to find 3334 certain 5343 things 8484";
var re2 = new RegExp(pattern, "g");
var str1 = str.replace(re2, "****");
alert(str1);
var pattern2 = pattern.replace(re, "\\D");
var re3 = new RegExp(pattern2, "g");
var str2 = str.replace(re3, "****");
alert(str2);
};
//--><!]]>
</script>
<body>
<p>content</p>
</body>
</html>
最初的字符串例如以下:
I want 1111 to find 3334 certain 5343 things 8484
打印出的第一个字符串。是将最初字符串中的数字转换为星号:
I want **** to find **** certain **** things ****
打印出的第二个字符串是相同的字符串,可是字符已经转换为星号:
****nt 1111******** 3334******** 5343********8484
虽然这个样例非常easy,它展示了当你想要在正則表達式字符本身上搜索的时候所遇到的一些挑战。