C++、Java、JavaScript中的正则表达式

时间:2022-09-02 14:41:42

C++(VS2013编译器):http://msdn.microsoft.com/zh-cn/library/bb982727.aspx#grammarsummary

Java:              http://docs.oracle.com/javase/7/docs/api/java/util/regex/Pattern.html

JavaScript:         http://www.w3school.com.cn/jsref/jsref_obj_regexp.asp

这儿主要是JS中的正则表达式:

  1. 正则表达式是用于匹配字符串中字符组合的模式。 一种几乎可以在所有的程序设计语言里和所有的计算机平台上使用的文字处理工具。它可以用来查找(搜索)特定的信息,也可以用来查找并编辑(替换)特定的信息。

  2. 核心是匹配,匹配位置或者匹配字符。

  3. 在 JavaScript 中,正则表达式也是对象。

  4. 这些模式被用于 RegExp 的 exec 和 test 方法, 以及 String 的 matchreplacesearch 和 split 方法。

二. 创建正则表达式

2.1 正则表达式的创建可以有以下三种方法。

2.1.1 字面量

/pattern/flags

let reg1 = /jing ke tong xue/g;
console.log(reg1); // /jing ke tong xue/g
2.1.2 构造函数

new RegExp(pattern [, flags])

let reg2 = new RegExp('jing ke tong xue', 'g');
console.log(reg2); // /jing ke tong xue/g
2.1.3 工厂符号

RegExp(pattern [, flags])

let reg3 = RegExp('jing ke tong xue', 'g');
console.log(reg3); // /jing ke tong xue/g

2.2 字面量、构造函数、工厂符号在创建正则表达式中的异同

2.2.1 共同点

三种方法都可以创建正则表达式,正则表达式的文本pattern为必须参数,标志符flagsg、i、m、y、u五个可选、可任意搭配参数。

g:(global) 全局模式,即模式将应用于所有的字符串,而非发现第一个匹配项时立即停止;
i: (case-insensitive) 表示不区分大小写模式
m: (multiline)表示多行模式,即在文本的末尾时会继续查找下一行是否存在于模式匹配的项
2.2.2 不同点

构造函数和工厂符号除了相差一个new关键字外没有什么不同,但是不推荐工厂符号的形式创建正则表达式。下面主要说一下字面量和构造函数的形式创建正则表达式的不同之处。

  1. 当表达式被赋值时,字面量形式提供正则表达式的编译(compilation)状态,当正则表达式保持为常量时使用字面量。例如当你在循环中使用字面量构造一个正则表达式时,正则表达式不会在每一次迭代中都被重新编译(recompiled)

  2. 正则表达式对象的构造函数,如new RegExp('jing ke tong xue')提供了正则表达式运行时编译(runtime compilation)。如果你知道正则表达式模式将会改变,或者你事先不知道什么模式,而是从另一个来源获取,如用户输入,这些情况都可以使用构造函数。

  3. ECMAScript 6开始,当第一个参数为正则表达式而第二个标志参数存在时,new RegExp(/jing ke tong xue/, 'g')不再抛出==TypeError== (“当从其他正则表达式进行构造时不支持标志”)的异常,取而代之,将使用这些参数创建一个新的正则表达式。

  4. 字面量方式pattern中所有字符都是元字符,所以不能进行变量值的拼接。通过构造函数的方式pattern中所有字符都是字符串,是可以进行字符串拼接的,同时对于特殊字符也是需要转义的。

  • 字符串变量拼接
const name = 'jing ke';

// 字符串拼接不会成功
let reg1 = /" + name + " tong xue/g;
console.log(reg1); // /" + name + " tong xue/g // 字符串拼接可以成功
let reg2 = new RegExp(name + ' tong xue', 'g');
console.log(reg2); // /jing ke tong xue/g
  • 特殊字符转义
const name = 'jing     ke';

// 匹配name,这里jing和ke之间可能有1个或多个空格
let reg1 = /jing\s+ke/g;
console.log(reg1); // /jing\s+ke/g
console.log(reg1.test(name)); // true // 这里创建的正则表达式和字面量方式创建的结果并不一样
let reg2 = new RegExp('jing\s+ke', 'g');
console.log(reg2); // /jings+ke/g
console.log(reg2.test(name)); // false // 这里我把reg3稍稍改造了一下,结果就和reg1一样了
let reg3 = new RegExp('jing\\s+ke', 'g');
console.log(reg3); // /jing\s+ke/g
console.log(reg3.test(name)); // true

再看一个特殊字符转义的例子

// 写一个正则表达式匹配反斜杠 \
const str = '\\'; // 这里str就是 \,反斜杠有特殊意义,下文介绍基本元字符会讲
// 字面量方式
let reg1 = /\\/g;
console.log(reg1); // /\\/g
console.log(reg1.test(str)); // true // 为什么是4个反斜杠,详见下文元字符介绍。自己在控制台试试1个,2个,3个会报什么错
let reg2 = new RegExp('\\\\', 'g');
console.log(reg2); // /\\/g
console.log(reg2.test(str)); // true

三. 正则表达式中特殊字符

3.1 标志字符

标志字符 含义
g 全局匹配,找到所有匹配,而不是在第一个匹配后停止。
i 忽略大小写。
m 多行,将开始和结束字符(^和$)视为在多行上工作(也就是,分别匹配每一行的开始和结束(由 \n 或 \r 分割),而不只是只匹配整个输入字符串的最开始和最末尾处。
u ES6新增,Unicode,将模式视为Unicode序列点的序列。
y ES6新增,粘性匹配,仅匹配目标字符串中此正则表达式的lastIndex属性指示的索引(并且不尝试从任何后续的索引匹配)。

3.2 基本元字符

基本元字符 含义
. 匹配除了换行符之外的任何单个字符
\ 在非特殊字符之前的反斜杠表示下一个字符是特殊的,不能从字面上解释。例如,没有前\b通常匹配小写b,无论它们出现在哪里。如果加了\,这个字符变成了一个特殊意义的字符,反斜杠也可以将其后的特殊字符,转义为字面量。例如,模式 /a*/ 代表会匹配0个或者多个a。相反,模式 /a\*/ 将*的特殊性移除,从而可以匹配像 a* 这样的字符串。
| 逻辑或操作符。
[...] 定义一个字符集合,匹配字符集合中的一个字符,在字符集合里面像 .\这些字符都表示其本身。
[^...] 对上面一个集合取非。
- 定义一个区间,例如[A-Z],其首尾字符在 ASCII 字符集里面。

3.3 数量元字符

量词 含义
* 等价于{0,},表示出现任意次,可以不出现。
+ 等价于{1,},表示至少出现一次,上不封顶。
? 等价于{0, 1}表示出现一次或零次。
{m} 等价于{m, m},标志正好出现m次,不能多也不能少。
{m,} 表示至少出现 m 次,上不封顶。

量词后面加?可以实现惰性匹配,对应关系如下:

贪婪量词 惰性量词
* *?
+ +?
? ??
{m} {m}?
{m,} {m,}?

3.4 锚字符(位置元字符)

字符 含义
^ 单独使用匹配表达式的开始。匹配字符串的开头,在多行检索中,匹配一行的开头。
$ 匹配表达式的结束。匹配字符串的结尾,在多行检索中,匹配一行的结尾。
\b 匹配一个单词的边界,简而言之,就是位于字符\w和字符\W之间的位置,或位于字符\w和字符串的开头或结尾之间的位置(但需要注意的是在字符组内[\b]匹配的是退格符)。
\B 匹配非单词边界。
(?=p) 匹配 p 前面的位置。零宽正向先行断言,要求接下来的字符都与p匹配,但不能包括匹配p的那些字符。
(?!p) 匹配不是 p 前面的位置。零宽负向先行断言,要求接下来的字符不与p匹配。

3.5 特殊元字符

字符 含义
\d 等价于[0-9],表示一位数字s。
\D 等价于[^0-9],表示一位非数字。除了ASCⅡ数字之外的任何字符。
\s 等价于[\t\v\n\r\f],表示空白符,包括空格,水平制表符(\t),垂直制表符(\v),换行符(\n),回车符(\r),换页符(\f)
\S 等价于[^\t\v\n\r\f],表示非空白符。
\w 等价于[0-9a-zA-Z],表示数字大小写字母和下划线。
\W 等价于[^0-9a-zA-Z],表示非单词字符。

四. 正则表达式的一些属性

4.1 RegExp.lastIndex

  • lastIndex 是正则表达式的一个可读可写的整型属性,用来指定下一次匹配的起始索引。

  • 只有正则表达式使用了表示全局检索的 "g" 标志时,该属性才会起作用。

如果 lastIndex 大于字符串的长度,则 regexp.test 和 regexp.exec 将会匹配失败,然后 lastIndex 被设置为 0。

如果 lastIndex 等于字符串的长度,且该正则表达式匹配空字符串,则该正则表达式匹配从 lastIndex 开始的字符串。

如果 lastIndex 等于字符串的长度,且该正则表达式不匹配空字符串 ,则该正则表达式不匹配字符串,lastIndex 被设置为 0。

否则,lastIndex 被设置为紧随最近一次成功匹配的下一个位置。

请看如下示例代码:

const str = 'jing ke tong xue jing ke tong xue jing ke tong xue jing ke tong xue';
let reg = /jing ke tong xue/g;
// lastIndex从0开始
console.log(reg.lastIndex); // 0
console.log(reg.test(str)); // true
console.log(reg.lastIndex); // 16
console.log(reg.test(str)); // true
console.log(reg.lastIndex); // 33
// lastIndex可修改
reg.lastIndex = 0;
console.log(reg.lastIndex); // 0
console.log(reg.test(str)); // true
console.log(reg.lastIndex); // 16
console.log(reg.test(str)); // true
console.log(reg.lastIndex); // 33
console.log(reg.test(str)); // false
console.log(reg.lastIndex); // 50
console.log(reg.test(str));// true
console.log(reg.lastIndex); // 67
console.log(reg.test(str));// false
// 上一次匹配失败,lastIndex重置为0
console.log(reg.lastIndex); // 0
console.log(reg.test(str));// true

4.2 RegExp.prototype.global

  • global属性表明正则表达式是否使用了 "g" 标志。

  • global的值是布尔对象,如果使用了 "g" 标志,则返回true;否则返回false。 "g" 标志意味着正则表达式应该测试字符串中所有可能的匹配。

  • global是一个正则表达式实例的只读属性。RegExp.prototype.globalwritableenumerableconfigurable属性均为false,无法直接更改此属性。

请看如下示例代码:

let reg1 = /jing ke tong xue/;
console.log(reg1.global); // false. let reg2 = /jing ke tong xue/g;
console.log(reg2.global); // true

4.3 RegExp.prototype.ignoreCase

  • ignoreCase属性表明正则表达式是否使用了 "i" 标志。

  • ignoreCase的值是布尔对象,如果使用了"i" 标志,则返回true;否则,返回false。"i"标志意味着在字符串进行匹配时,应该忽略大小写。
  • ignoreCase是正则表达式实例的只读属性。RegExp.prototype.ignoreCasewritableenumerableconfigurable属性均为false,无法直接更改此属性。

请看如下示例代码:

let reg1 = /jing ke tong xue/;
console.log(reg1.ignoreCase); // false. let reg2 = /jing ke tong xue/i;
console.log(reg2.ignoreCase); // true

4.4 RegExp.prototype.multiline

  • multiline属性表明正则表达式是否使用了 "m" 标志。

  • multiline的值是布尔对象,如果使用了"m" 标志,则返回true;否则,返回false。"m" 标志意味着一个多行输入字符串被看作多行。

  • multiline是正则表达式实例的一个只读属性。RegExp.prototype.multilinewritableenumerableconfigurable属性均为false,无法直接更改此属性。

请看如下示例代码:

let reg1 = /jing ke tong xue/;
console.log(reg1.multiline); // false. let reg2 = /jing ke tong xue/m;
console.log(reg2.multiline); // true

4.5 RegExp.prototype.unicode

  • unicode属性表明正则表达式带有"u" 标志。

  • unicode的值是Boolean,并且如果使用了 "u" 标志则为true;否则为false。"u" 标志开启了多种Unicode相关的特性。使用 "u" 标志,任何Unicode 代码点的转义都会被解释。

  • unicode是正则表达式独立实例的只读属性。RegExp.prototype.unicodewritableenumerable属性为falseconfigurable属性均为true,无法直接更改此属性。

请看如下示例代码:

let reg1 = /jing ke tong xue/;
console.log(reg1.unicode); // false. let reg2 = /jing ke tong xue/u;
console.log(reg2.unicode); // true

再看如下示例代码:

// 定义一个四个字节的 UTF-16 编码的字符
const str = '\uD83D\uDC2A'; let reg1 = /^\uD83D/;
// ES5不支持四个字节的 UTF-16 编码,会将其识别为两个字符,故而输出 true
console.log(reg1.test(str)); // true let reg2 = /^\uD83D/u;
// 加了u修饰符以后,ES6 就会识别其为一个字符,故而输出false
console.log(reg2.test(str)); // false

4.6 RegExp.prototype.sticky

  • sticky属性表明正则表达式带有"y" 标志。

  • sticky的值是 Boolean ,并且如果使用了"y"标志则为true;否则为false。"y" 标志指示搜索是否具有粘性,仅从正则表达式的lastIndex 属性表示的索引处为目标字符串匹配(并且不会尝试从后续索引匹配)。

  • sticky是正则表达式独立实例的只读属性。RegExp.prototype.stickywritableenumerable属性为falseconfigurable属性均为true,无法直接更改此属性。

请看如下示例代码:

let reg1 = /jing ke tong xue/;
console.log(reg1.sticky); // false. let reg2 = /jing ke tong xue/y;
console.log(reg2.sticky); // true

再看如下示例代码:

const str = 'test jing ke tong xue test jing ke tong xue';

let reg1 = /jing ke tong xue/;
// 没有y标识符,lastIndex始终为0,但是reg1并不具有粘性,并不从lastIndex号为开始
console.log(reg1.lastIndex); // 0
console.log(reg1.test(str)); // true
reg1.lastIndex = 5;
console.log(reg1.lastIndex); // 5
console.log(reg1.test(str)); // true
// 由于没有y标识符,在正则表达式匹配之后,lastIndex又被重置为0
console.log(reg1.lastIndex); // 0
console.log(reg1.test(str)); // true let reg2 = /jing ke tong xue/y;
// 第一次匹配将从0号位开始
console.log(reg2.lastIndex); // 0
console.log(reg2.test(str)); // false
// 第二次一次匹配将从5号位开始
reg2.lastIndex = 5;
console.log(reg2.lastIndex); // 5
console.log(reg2.test(str)); // true
// 下一次匹配将从21号位开始
console.log(reg2.lastIndex); // 21
console.log(reg2.test(str)); // false
// 上一次匹配失败,lastIndex重置为0;下一次匹配将从0号位开始
console.log(reg2.lastIndex);

4.7 RegExp.prototype.source

  • source 属性返回一个值为当前正则表达式对象的模式文本的字符串。该字符串不会包含正则字面量两边的斜杠以及任何的标志字符。

请看如下示例代码:

let reg = /jing ke tong xue/gimuy;
console.log(reg.source); // jing ke tong xue
// source无法被修改,不会生效
reg.source = 'tong xue jing ke';
console.log(reg); // /jing ke tong xue/gimuy

4.8 RegExp.prototype.flags

  • flagsES6新增属性,返回一个由当前正则表达式对象的标志组成的字符串。

  • 标志以字母表顺序排序。(从左到右gimuy)。

  • flags是正则表达式独立实例的只读属性。RegExp.prototype.flagswritableenumerable属性为falseconfigurable属性均为true,无法直接更改此属性。

请看如下示例代码:

let reg = /jing ke tong xue/gimuy;
console.log(reg.flags); // jing ke tong xue
// flags无法被修改,不会生效
reg.flags = 'g';
console.log(reg); // /jing ke tong xue/gimuy

flags属性为ES6新增属性,ES6以前可用如下Polyfill。

if (RegExp.prototype.flags === undefined) {
Object.defineProperty(RegExp.prototype, 'flags', {
writable: false, // 默认为false,写上便于理解
enumerable: false, // 默认为false,写上便于理解
configurable: true,
get: function() {
return this.toString().match(/[gimuy]*$/)[0];
}
});
}

五. 正则表达式的一些方法

5.1 RegExp.prototype.test

  • 语法 reg.test(str)str:用来与正则表达式匹配的字符串。

  • test() 方法执行一个检索,用来查看正则表达式与指定的字符串是否匹配。

  • 如果正则表达式与指定的字符串匹配 ,返回true,否则false

const str = 'jing ke tong xue';
let reg1 = /^jing/;
// 判断str是不是以jing开头
console.log(reg1.test(str)); // true let reg2 = /^ke/;
// 判断str是不是以ke开头
console.log(reg2.test(str)); // fase

在设置有全局标志g的正则使用test方法。

如果正则表达式设置了全局标志,test方法的执行会改变正则表达式的 lastIndex 属性。连续的执行test方法,后续的执行将会从 lastIndex 处开始匹配字符串。如果 test 方法返回匹配失败 false,lastIndex 属性将会被重置为0。

const str = 'jing ke tong xue jing ke tong xue jing ke tong xue';
let reg = /jing ke/g; console.log(reg.lastIndex); // 0
console.log(reg.test(str)); // true
console.log(reg.lastIndex); // 7
console.log(reg.test(str)); // true
console.log(reg.lastIndex); // 24
console.log(reg.test(str)); // true
console.log(reg.lastIndex); // 41
console.log(reg.test(str)); // false
console.log(reg.lastIndex); // 0

5.2 RegExp.prototype.exec

  • 语法reg.exec(str)str:要匹配正则表达式的字符串。 exec() 方法在一个指定字符串中执行一个搜索匹配。返回一个结果数组或 null

  • 如果匹配成功,exec() 方法返回一个数组,并更新正则表达式对象的属性。返回的数组将完全匹配成功的文本作为第一项,将正则括号里匹配成功的作为数组填充到后面。

  • 如果匹配失败,exec() 方法返回 null

C++、Java、JavaScript中的正则表达式的更多相关文章

  1. 转载 javascript中的正则表达式总结 一

    定义正则表达式的方法 定义正则表达式的方法有两种:构造函数定义和正则表达式直接量定义.例如: var reg1 = new RegExp('\d{5, 11}'); // 通过构造函数定义 var r ...

  2. JavaScript中的正则表达式(终结篇)

    JavaScript中的正则表达式(终结篇) 在之前的几篇文章中,我们了解了正则表达式的基本语法,但那些语法不是针对于某一个特定语言的.这篇博文我们将通过下面几个部分来了解正则表达式在JavaScri ...

  3. Javascript中的正则表达式

    Javascript中的正则表达式 刚开始接触正则表达式的时候,觉得这是个很死板的东西(没办法,计算机不能像人眼一样能很快的辨认出我们需要的结果,它需要一定的规则来对它进行限制),了解的越多,发现这个 ...

  4. 浅谈JavaScript中的正则表达式

    引言 对于正则表达式我想作为程序员肯定使用过它,那天书般的表达方式,我用一次就记住它了.这篇博客先介绍一些正则表达式的内容,然后介绍JavaScript中对正则表达式特有的改进.下面开始介绍正则表达式 ...

  5. 浅谈JavaScript中的正则表达式(适用初学者观看)

    浅谈JavaScript中的正则表达式 1.什么是正则表达式(RegExp)? 官方定义: 正则表达式是一种特殊的字符串模式,用于匹配一组字符串,就好比用模具做产品,而正则就是这个模具,定义一种规则去 ...

  6. 精通 JavaScript中的正则表达式

    精通 JS正则表达式 (精通?标题党 ) 正则表达式可以: •测试字符串的某个模式.例如,可以对一个输入字符串进行测试,看在该字符串是否存在一个电话号码模式或一个信用卡号码模式.这称为数据有效性验证  ...

  7. Java语言中的正则表达式

    正则表达式是什么? 正则表达式是一种强大而灵活的文本处理工具.初学正则表达式时,其语法是一个难点,但它确实是一种简洁.动态的语言.正则表达式提供了一种完全通用的方式,能够解决各种字符串处理相关的问题: ...

  8. JavaScript中的正则表达式详解

    摘要:javascript中的正则表达式作为相当重要的知识,本文将介绍正则表达式的相关知识和用法. 正则表达式(Regular Expression)是一门简单语言的语法规范,是强大.便捷.高效的文本 ...

  9. (译)JavaScript 中的正则表达式(RegEx)实操——快速掌握正则表达式,伴有随手可练的例子————(翻译未完待续)

    (原文:https://blog.bitsrc.io/a-beginners-guide-to-regular-expressions-regex-in-javascript-9c58feb27eb4 ...

随机推荐

  1. easyuidatagrid中load,reload,loadData的区别。

    摘要:datagrid中有load,reload,loadData那三个方式,皆是加载数据的,但又有差别.下面让我们一起来看看: 首先,load方法,比如我已经定义一个datagrid的id为grid ...

  2. 常见的NoSql系统使用场景分析--转载

    •Cassandra •特性:分布式与复制的权衡\根据列和键范围进行查询\BigTable类似的功能:列,列族\写比读快很多 •最佳适用:写操作较多,读比较少的时候.如果你的系统都是基于Java的时候 ...

  3. 解决安装rpm时lib冲突:libstdc++-2-libc6.1-1-2.9.0.so from install of compat-libstdc++-7.3-2.96.118 conflicts with file from ...

    sudo rpm -ivh xxx.rpm -aid --force [oracle@localhost Oracle]$ .i386.rpm compat-libstdc++-devel-.i386 ...

  4. JMeter基础

    转载自虫师-http://www.cnblogs.com/fnng/archive/2012/12/21/2828440.html JMeter 介绍: 一个非常优秀的开源的性能测试工具. 优点:你用 ...

  5. 响应式移动端去除css的hover和jq的hover还有input在苹果下的默认样式

    去除css的hover: /*直接给body添加ontouchstart*/ <body ontouchstart> 去除jq的hover: var winW01 = $(window). ...

  6. 好用的sitemap生成器—GY SiteMap

    好用的sitemap生成器-GY SiteMap 下载地址:http://www.wyxxw.cn/download-detail-6-8-14.html 网站地图可以更好的帮助搜索引擎抓取.收录网站 ...

  7. android&colon;baselineAligned属性

    对于可以显示文字的View(如TextView,Button等),它的baseline 指的是这个UI控件中文字Text的baseline 到UI控件顶端的偏移值,可以通过View 的getBasel ...

  8. es6 模本字符串拼接方法 &grave;&grave;

    1.字符串拼接  可以使用 es6  ` ` 配合 ${xxx} 具体操作上代码 <!DOCTYPE html> <html lang="en"> < ...

  9. 01 前言&sol;基础设施 - DevOps之路

    01 前言/基础设施 - DevOps之路 文章Github地址,欢迎start:https://github.com/li-keli/DevOps-WiKi 简介 基础架构采用DevOps设计思想, ...

  10. js中typeof与instanceof用法

    今天写JS代码,遇到动态生成多个名称相同的input复选按钮 需要判断其是否是数组,用到了if (typeof(document.MapCheckMgr.checkid)!="undefin ...