正则表达式

正则表达式起源于对形式语言(formal language)的数学研究,它趋向于极致而简洁的书写风格,所有的字符挤在一起,不仅难以阅读,而且在维护时也非常困难。Javascript正则表达式借鉴自Perl,它不支持注释和空白,且处在不同位置的相同字符都可能代表不同的意义。 但是我们为何又要使用它呢? 这主要是因为,相比等效的字符串处理,Javascript正则表达式有着明显的性能优势。

参考:https://en.wikipedia.org/wiki/Formal_language

下面通过例子来感受一下:

/**
 * 处理一个url串,并捕获其中的协议名、主机名(*)、端口号、路径名、查询条件和哈希值
 * 其中,除了主机名是捕获型分组外,其他的皆为非捕获型
 */
// 以简书为例
var url = 'http://www.jianshu.com:8080/u/101db3165437?user=JSoon#info';
// 处理后的url
var parsed = /^(?:([a-zA-Z]+):)?(\/{0,2})([a-zA-Z0-9\.\-]*)(?::([0-9]+))?(?:\/([^?#]*))?(?:\?([^#]*))?(?:\#(.*))?$/.exec(url);
// 在控制台打印
console.log(parsed);

结果如下图:


QQ截图20170108152821.png

首先来看parsedregexp.exec(string)返回一个结果数组,数组的第一项为该正则表达式的匹配结果,不计入分组。
参考:RegExp.prototype.exec()
parsed[1]开始直到parsed[7],则是正则表达式分组所匹配到的值。

正则表达式为两个正斜杠之间所夹的符号串/regexp/组成,在本例中,第一个/后的^表示以第一个分组所匹配的字符串开始,它像一个锚,只会匹配以次开头的字符串,否则返回null。最后一个/前的$表示这个字符串的结束,这就能确保匹配的精确性。


分组一:

// 协议名
(?:([a-zA-Z]+):)? // 匹配一段后边紧跟一个冒号的字符串。如果没有,则会返回undefined,因为+告诉了正则匹配器,必须得到至少一个英文字符
// 匹配结果
console.log(parsed[1]); // "http"

(?:)表示这是一个非捕获型分组,后面的?表明这是一个非贪婪性匹配?等同于{0,1}。表示如果整个字符串中都没有匹配到这个字符串,也不会影响匹配的进行。若去掉这个?,而字符串中又没有如http:之类的子串,那么正则匹配将立即结束,并返回null

其内部有一个捕获型分组([a-zA-Z]+)[a-zA-Z]是一个字符集,它指定了一组字符串,这里表示所有的大小写英文字母,后边的+表示贪婪性匹配,等同于{1,},即至少匹配一个英文字母。([a-zA-Z]+)后边的:表示这段英文字母后紧接着是一个冒号,如若不是,匹配也会失败。

分组二:

// 斜杠
(\/{0,2}) // 匹配0到2个连续的斜杠。如果没有斜杠,则会返回""空串
// 匹配结果
console.log(parsed[2]); // "//"

这个很好理解,在正则中,若想将斜杠之类的特殊字符按照字面量来匹配,则必须使用反斜杠前缀对其进行转义。这里一个小窍门是,如果你拿不准哪些特殊字符需要转义,一个保险的做法是,给任何特殊字符都添加一个反斜杠前缀来使其字面量化。注意反斜杠前缀并不能使字母或数字字面量化。

分组三:

// 主机名
([a-zA-Z0-9\.\-]*) // 匹配至少0次包含大小写英文字母,数字,点号和连字符
// 匹配结果
console.log(parsed[3]); // "www.jianshu.com"

.-被转义,将.转义是一种保险的做法,因为这里我并不确定它在字符集中是否代表其他含义;而将-转义的目的是因为连字符在字符集中表示范围,如[0-9]表示[0123456789]

分组四:

// 端口号
(?::([0-9]+))? // 匹配以冒号开始,以及之后的数字。如果没有,其中的捕获分组会返回undefined,因为+告诉了正则匹配器,必须得到至少一个数字
// 匹配结果
console.log(parsed[4]); // "8080"

分组五:

// 路径名
(?:\/([^?#]*))? // 匹配以斜杠开始,以及除?和#之外所有的字符
// 匹配结果
console.log(parsed[5]); // "u/101db3165437"

分组六:

// 查询条件
(?:\?([^#]*))? // 匹配以?开始,以及除#之外所有的字符
// 匹配结果
console.log(parsed[6]); // "user=JSoon"

分组七:

// 哈希值
(?:\#(.*))? // 匹配以#开始,除行结束符以外的所有字符
// 匹配结果
console.log(parsed[7]); // "info"

特别的,一个未被转移的.会匹配除行结束符\n\r以外的任何字符。

若还需要对匹配结果进行再匹配,则可以对结果再次进行正则处理,这里就不细说了。

当然,除了用正则表达式字面量来创建正则表达式外,还可以使用RegExp构造函数来实现。RegExp适用于需要动态生成正则表达式,而不是事先就明确正则条件的情况时使用。
参考:https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/RegExp

可以处理正则表达式的方法:

regexp.exec // 返回匹配结果的数组
regexp.test // 返回true or false
string.match // 返回与regexp.exec相同
string.replace // 用正则对匹配结果进行替换,返回替换后的新字符串
string.search // 返回匹配到的字符串的第一个字符的位置,若匹配失败,则返回-1
string.split // 用正则匹配到的字符作为分割器,然后返回分割后的各个字符的数组

欢迎交流,完。

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

推荐阅读更多精彩内容