正则表达式:实例

使用插入语

任何正则表达式的插入语都会使这部分匹配的副字符串被记忆。一旦被记忆,这个副字符串就可以被调用于其它用途,如同 使用括号的子字符串匹配之中所述。
比如, /Chapter (\d+)\.\d*/ 解释了额外转义的和特殊的字符,并说明了这部分模式应该被记忆。它精确地匹配后面跟着一个以上数字字符的字符 'Chapter ' (\d 意为任何数字字符,+ 意为1次以上),跟着一个小数点(在这个字符中本身也是一个特殊字符;小数点前的 \ 意味着这个pattern必须寻找字面字符 '.'),跟着任何数字字符0次以上。 (\d 意为数字字符, * 意为0次以上)。另外,插入语也用来记忆第一个匹配的数字字符。
此模式可以匹配字符串"Open Chapter 4.3, paragraph 6",并且'4'将会被记住。此模式并不能匹配"Chapter 3 and 4",因为在这个字符串中'3'的后面没有点号'.'。
括号中的"?:",这种模式匹配的子字符串将不会被记住。比如,(?:\d+)匹配一次或多次数字字符,但是不能记住匹配的字符。


使用正则表达式

正则表达式可以被用于RegExpexectest方法以及 Stringmatchreplacesearchsplit方法。这些方法在JavaScript 手册中有详细的解释。
当你想要知道在一个字符串中的一个匹配是否被找到,你可以使用test或search方法;想得到更多的信息(但是比较慢)则可以使用exec或match方法。如果你使用exec或match方法并且匹配成功了,那么这些方法将返回一个数组并且更新相关的正则表达式对象的属性和预定义的正则表达式对象(详见下)。如果匹配失败,那么exec方法返回null(也就是false)。
在接下来的例子中,脚本将使用exec方法在一个字符串中查找一个匹配。

var myRe = /d(b+)d/g;
var myArray = myRe.exec("cdbbdbsbz");

如果你不需要访问正则表达式的属性,这个脚本通过另一个方法来创建myArray:

var myArray = /d(b+)d/g.exec("cdbbdbsbz");

如果你想通过一个字符串构建正则表达式,那么这个脚本还有另一种方法:

var myRe = new RegExp("d(b+)d", "g");
var myArray = myRe.exec("cdbbdbsbz");

通过这些脚本,匹配成功后将返回一个数组并且更新正则表达式的属性,如下表所示:

对象 属性或索引 描述 在例子中对应的值
myArray 匹配到的字符串和所有被记住的子字符串。 0:"dbbd"
1:"bb"
myArray index 在输入的字符串中匹配到的以0开始的索引值。 index:1
myArray input 初始字符串。 input:"cdbbdbsbz"
myArray [0] 匹配到的最终字符。 0:"dbbd"
myArray [1] 被记住的子字符串。 1:"bb"
myArray length 匹配到的字符串和所有被记住的子字符串的长度。 length:2
myRe lastIndex 下一个匹配的索引值。(这个属性只有在使用g参数时可用在 通过参数进行高级搜索 一节有详细的描述.) 5
myRe source 模式文本。在正则表达式创建时更新,不执行。 "d(b+)d"

在这个例子中如第二种形式所示,你可以使用一个正则表达式创建一个没有分配给变量的对象初始化容器。如果你这样做,那么,每一次使用时都好比在使用一个新的正则表达式。因为这个原因,如果你使用这个未分配给一个变量的正则表达式,你将在随后不能访问这个正则表达式的属性。例如,假如你有如下脚本:

var myRe = /d(b+)d/g;
var myArray = myRe.exec("cdbbdbsbz");
console.log("The value of lastIndex is " + myRe.lastIndex);

这个脚本输出如下:

The value of lastIndex is 5

然而,如果你有如下脚本:

var myArray = /d(b+)d/g.exec("cdbbdbsbz");
console.log("The value of lastIndex is " + /d(b+)d/g.lastIndex);

它显示为:

The value of lastIndex is 0

当发生/d(b+)d/g使用两个不同状态的正则表达式对象,lastIndex属性会得到不同的值。如果你需要访问一个正则表达式的属性,则需要创建一个对象初始化生成器,你应该首先把它赋值给一个变量。


使用括号的子字符串匹配

一个正则表达式模式使用括号,将导致相应的子匹配被记住。例如,/a(b)c /可以匹配字符串“abc”,并且记得“b”。回调这些括号中匹配的子串,使用数组元素[1],……[n]。
使用括号匹配的子字符串的数量是无限的。返回的数组中保存所有被发现的子匹配。下面的例子说明了如何使用括号的子字符串匹配。

下面的脚本使用replace()方法来转换字符串中的单词。在匹配到的替换文本中,脚本使用替代的$1,$2表示第一个和第二个括号的子字符串匹配。

var re = /(\w+)\s(\w+)/;
var str = "John Smith";
var newstr = str.replace(re, "$2, $1");
console.log(newstr);

这个表达式输出 "Smith, John"。


通过标志进行高级搜索

正则表达式有五个可选参数进行全局和不分大小写搜索。这些参数既可以单独使用也可以一起使用在任何顺序和包含正则表达式的部分中。
包含一个标志的正则表达式,使用这个表达式:

var re = /pattern/flags;

var re = new RegExp("pattern", "flags");

flags应替换g、i、m、u、y或其组合。
值得注意的是,标志是一个正则表达式的一部分,它们在接下来的时间将不能添加或删除。

例如,re = /\w+\s/g 将创建一个查找一个或多个字符后有一个空格的正则表达式,或者组合起来像此要求的字符串。
这段代码将输出 ["fee ", "fi ", "fo "]。

var re = /\w+\s/g;
var str = "fee fi fo fum";
var myArray = str.match(re);
console.log(myArray);

当使用构造函数创造正则对象时,需要常规的字符转义规则(在前面加反斜杠 \)。在这个例子中,你可以将:

var re = /\w+\s/g;

替换成:

var re = new RegExp("\w+\s", "g");

两者是等价的,可以能获取到相同的结果。

m标志用于指定多行输入字符串应该被视为多个行。如果使用m标志,^和$匹配的开始或结束输入字符串中的每一行,而不是整个字符串的开始或结束。


例子:使用正则改变数据结构
下例使用 replace 方法 (继承自 String)去匹配姓名 *first last *输出新的格式 *last*, *first*。脚本中使用 $1$2 指明括号里先前的匹配.

var re = /(\w+)\s(\w+)/;
var str = "John Smith";
var newstr = str.replace(re, "$2, $1");
console.log(newstr);

显示 "Smith, John".


例子:正则表达式分割不同的行

var text = 'Some text\nAnd some more\r\nAnd yet\rThis is the end';
var lines = text.split(/\r\n|\r|\n/);
console.log(lines); // logs [ 'Some text', 'And some more', 'And yet', 'This is the end' ]

正则表达式需要注意模式顺序。


例子:在多行中使用正则表达式

var s = "Please yes\nmake my day!";

s.match(/yes.*day/);
// Returns null
s.match(/yes[^]*day/);
// Returns 'yes\nmake my day'


例子: 使用带有 ”sticky“ 标志的正则表达式
该例展示了,如何在正则表达式上使用 sticky 标志,用来匹配多行输入的单独行。

var text = "First line\nsecond line";
var regex = /(\S+) line\n?/y;
var match = regex.exec(text);
console.log(match[1]); // logs "First"
console.log(regex.lastIndex); // logs 11
var match2 = regex.exec(text);
console.log(match2[1]); // logs "Second"
console.log(regex.lastIndex); // logs "22"
var match3 = regex.exec(text);
console.log(match3 === null); // logs "true"

可以使用 try { … } catch { … } 来测试运行时(run-time)是否支持 sticky 标志。这种情况下,必须使用 eval(…) 表达式或 RegExp(regex-string, flags-string) 语法(这是由于 /regex/flags 表示法将会在编译时刻被处理,因此在 catch 语句块处理异常前就会抛出一个异常。例如:

var supports_sticky;
try { RegExp('','y'); supports_sticky = true; }
catch(e) { supports_sticky = false; }
alert(supports_sticky); // alerts "false" in Firefox 2, "true" in Firefox 3+


例子:使用正则表达式和 Unicode 字符
正如上面表格提到的,\w 或 \W 只会匹配基本的 ASCII 字符;如 'a' 到 'z'、 'A' 到 'Z'、 0 到 9 及 '_'。为了匹配其他语言中的字符,如西里尔(Cyrillic)或 希伯来语(Hebrew),要使用 \uhhhh,"hhhh" 表示以十六进制表示的字符的 Unicode 值。下例展示了怎样从一个单词中分离出 Unicode 字符。

var text = 'Образец text на русском языке';
var regex = /[\u0400-\u04FF]+/g;

var match = regex.exec(text);
console.log(match[0]); // logs 'Образец'
console.log(regex.lastIndex); // logs '7'

var match2 = regex.exec(text);
console.log(match2[0]); // logs 'на' [did not log 'text']
console.log(regex.lastIndex); // logs '15'

这里有一个外部资源,用来获取 Unicode 中的不同区块范围:Regexp-unicode-block


例子:从 URL 中提取子域名

var url = 'http://xxx.domain.com';
console.log(/[^.]+/.exec(url)[0].substr(7)); // logs 'xxx'

正则表达式一: 构建正则表达式
正则表达式二: 模式的构成

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,816评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,729评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,300评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,780评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,890评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,084评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,151评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,912评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,355评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,666评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,809评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,504评论 4 334
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,150评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,882评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,121评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,628评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,724评论 2 351

推荐阅读更多精彩内容