开局一张图
分组相关
- 忽略分组(?:exp)
有时使用括号"()"的目的不是捕获分组, 而是不得不使用, 比如说(ABC|abc), 只是为了表达一个字符串的"或"关系
这时就要使用到忽略分组
(?:exp)
JavaScript中的正则表达式
正则表达式可以被用于 RegExp 的 exec 和 test 方法以及 String 的 match[All]、replace、search 和 split 方法。
为什么会有这么多方法,以及模式 /i(忽略) /m(多行) /g(全局)
的意义是?
先看 RegExp 的 exec 和 test 方法,以及字符串的 match[All] 方法:
const { log, table } = console;
(function main() {
let regex = /(.*).js/g;
let str = 'START a.js b.js
c.js END';
// test: 测试字符串是否包含正则内容,因此只要找到第一个匹配就返回true,忽略/g标志
let result = regex.test(str);
log(result)
})();
// true
const { log, table } = console;
(function main() {
let regex = /(.*).js/g;
let str = 'START a.js b.js
c.js END';
// exec: 执行一次匹配操作,并为结果分组,忽略/g标志
let result = regex.exec(str);
table(result)
})();
/*
Array(2)
0: "START a.js b.js"
1: "START a.js b"
groups: undefined
index: 0
input: "START a.js b.js ↵ c.js END"
length: 2
__proto__: Array(0)
*/
const { log, table } = console;
(function main() {
let regex = /(.*).js/;
let str = 'START a.js b.js
c.js END';
// match: 执行匹配操作,若无/g标志,则只匹配第一个结果,并返回该分组
let result = str.match(regex);
table(result);
})();
/*
Array(2)
0: "START a.js b.js"
1: "START a.js b"
groups: undefined
index: 0
input: "START a.js b.js ↵ c.js END"
length: 2
__proto__: Array(0)
*/
const { log, table } = console;
(function main() {
let regex = /(.*).js/g;
let str = 'START a.js b.js
c.js END';
// match: 执行匹配操作,若有/g标志,则获取多个匹配结果,不进行分组,返回匹配到的字符数组
let result = str.match(regex);
table(result);
})();
/*
Array(2)
0: "START a.js b.js"
1: " c.js"
length: 2
__proto__: Array(0)
*/
const { log, table } = console;
(function main() {
let regex = /(.*).js/g;
let str = 'START a.js b.js
c.js END';
// matchAll: 在上一种匹配的基础上,对每个结果分组,返回值是个可迭代对象
let result = str.matchAll(regex);
table([...result]); // 转换为数组
})();
/*
Array(2)
0: Array(2)
0: "START a.js b.js"
1: "START a.js b"
groups: undefined
index: 0
input: "START a.js b.js ↵ c.js END"
length: 2
__proto__: Array(0)
1: Array(2)
0: " c.js"
1: " c"
groups: undefined
index: 17
input: "START a.js b.js ↵ c.js END"
length: 2
__proto__: Array(0)
length: 2
__proto__: Array(0)
*/
Kotlin native 编写的regex工具
import platform.posix.*
fun help() {
println("""
|regex 帮助程序
|
| r, regex 从命令行提供一个正则表达式,匹配最后一个参数
| s, string 从命令行提供一个字符串,用最后的正则表达式匹配
|
""".trimMargin())
}
fun main(args: Array<String>) {
if (args.size != 3) {
return help()
}
var regex: Regex?
var string: String?
when (args[0]) {
"r", "regex" -> {
regex = args[1].toRegex()
string = args[2]
}
"s", "string" -> {
string = args[1]
regex = args[2].toRegex()
}
else -> {
return help()
}
}
println("regex: $regex
string: $string")
with (regex.matchEntire(string)) {
if (this == null) {
return println("匹配结果:不匹配")
}
println("匹配结果:")
groupValues.forEachIndexed { index, value ->
println("$index $value")
}
}
}
String.prototype.match和String.prototype.matchAll的区别
> [...'abcabc'.matchAll(/a(.*?)c/g)]
[
[ 'abc', 'b', index: 0, input: 'abcabc', groups: undefined ],
[ 'abc', 'b', index: 3, input: 'abcabc', groups: undefined ]
]
> [...'abcabc'.match(/a(.*?)c/g)]
[ 'abc', 'abc' ]