正则表达式的全局匹配模式

首先,要明确一点,所有的正则表达式都有一个lastIndex属性,用于记录上一次匹配结束的位置。如果不是全局匹配模式,那lastIndex的值始终为0,在匹配过一次后,将会停止匹配。

正则表达式的全局匹配模式,就是在创建正则表达式的时候使用g标识符或者将global属性设置为true,在全局匹配模式下,正则表达式会对指定要查找的字符串执行多次匹配。每次匹配使用当前正则对象的lastIndex属性的值作为在目标字符串中开始查找的起始位置。如果找不到匹配的项lastIndex的值会被重新设置为0

理解了上面的话,下面代码的结果就很清晰了:

var regex = /abc/g;
var str = '123#abc';
console.log(regex.lastIndex);   // 0
console.log(regex.test(str));   // true
console.log(regex.lastIndex);   // 7
console.log(regex.test(str));   // false
console.log(regex.lastIndex);   // 0
console.log(regex.test(str));   // true
console.log(regex.lastIndex);   // 7
console.log(regex.test(str));   // false

今天在写表单验证的时候遇到一个问题,每当偶数次点击的时候就会报错,就是这个问题造成的,解决方法也很简单,就是去掉正则表达式里面的g

关于RegExp.prototype.exec(str)方法和String.prototype.math(rgExp)方法:

RegExp.prototype.exec(str)方法返回NULL或返会一个数组,在数组的第0个元素存放的是在字符串str中查找到的匹配内容,1n个元素返回的是在模式中使用括号"()"指定的子匹配项的内容。

在没有使用全局标志时String.prototype.math(rgExp)方法和RegExp.prototype.exec(str)的行为类似。当设置了全局匹配标志时String.prototype.math(rgExp)方法返回的数组项元素0n中包含了所有匹配到的项不包含子匹配项。这时可以使用RegExp.$1..$9获取9个子匹配。


js正则表达式test()方法

test()方法是正则表达式的一个方法,用于检测一个字符串是否匹配某个模式.
test方法检查字符串是否与给出的正则表达式模式相匹配,如果是则返回 true,否则就返回 false

每个正则表达式都有一个lastIndex属性,用于记录上一次匹配结束的位置.

语法:regexp.test(str)

在全局匹配模式下

对于同一个正则对象重复调用就会出现下一次的匹配位置从上一次匹配结束的位置开始,解决方法重置lastIndex0

let reg = /^[\d]{2}$/g;
	let str = "12";
	console.log(reg.test(str));     //返回true
	let = "123";
	console.log(reg.test(str));     //从数字3开始匹配,只有一个数字,故返回false

重置lastIndex0

 let reg = /^[\d]{2}$/g;
	let str = "12";
	console.log(reg.test(str));     //返回true
	let = "123";
	reg.lastIndex = 0;
	console.log(reg.test(str));     //返回true

在非全局匹配模式下,则不存在这个问题

let reg = /^[\d]{2}$/;
	let str = "12";
	console.log(reg.test(str));     //返回true
	let = "123";
	console.log(reg.test(str));     //返回true

另外,test()方法和数组的forEach()方法一起使用可能达不到预期结果,在for循环下,同样如此,如下

let line = '1a 123 123 12';
let lines = line.split(' ');
let reg = /^[\d]+$/g;
let res = 0;
lines.forEach( function(element, index) {
	console.log(reg.test(element));  // flase true 交替出现	
});

使用forEach方法对数组中字符串进行test测试,会出现flase true 交替出现的现象,先出现false还是true则取决数组第一个元素匹配的结果。

同样的,在非全局匹配模式下,则不存在这个问题,这里去掉全局匹配g才可得到预期结果

let line = '1a 123 123 12'
	let lines = line.split(' ');
    let reg = /^[\d]+$/;
    let res = 0;
    lines.forEach( function(element, index) {
    	console.log(reg.test(element));  	// false true true true
    });
 
<think> 我们正在讨论Qt中正则表达式全局匹配方法。在Qt中,使用QRegularExpression类来处理正则表达式,而全局匹配可以通过多次匹配或使用全局匹配模式来实现。 关键点: 1. 使用QRegularExpression::globalMatch函数,它返回一个QRegularExpressionMatchIterator迭代器,用于遍历所有匹配项。 2. 设置匹配模式:可以使用QRegularExpression::MatchType中的相关选项,但全局匹配主要使用globalMatch函数。 步骤: a. 创建QRegularExpression对象,并设置模式。 b. 调用globalMatch函数,传入要匹配的字符串。 c. 使用返回的迭代器遍历所有匹配。 示例代码(C++): ```cpp #include <QRegularExpression> #include <QRegularExpressionMatchIterator> #include <QString> void globalRegexMatchExample(const QString &pattern, const QString &text) { QRegularExpression re(pattern); QRegularExpressionMatchIterator iter = re.globalMatch(text); while (iter.hasNext()) { QRegularExpressionMatch match = iter.next(); // 使用match.captured()获取匹配的字符串 QString captured = match.captured(); // 处理每个匹配... } } ``` 注意:如果正则表达式有捕获组,可以使用match.captured(n)来获取特定捕获组的内容。 另外,全局匹配也可以通过循环匹配直到结束来实现,但使用globalMatch更简便。 引用:Qt官方文档中关于QRegularExpression的globalMatch函数的说明[^1]。 生成相关问题: 1. 在Qt中如何获取正则表达式匹配的捕获组? 2. 如何处理Qt正则表达式匹配中的错误? 3. Qt正则表达式支持哪些特殊语法? 4. 如何设置正则表达式为大小写不敏感? </think> 在 Qt 中实现正则表达式全局匹配,主要通过 `QRegularExpression` 和 `QRegularExpressionMatchIterator` 类完成。以下是详细实现方法: ### 核心方法 ```cpp #include <QRegularExpression> #include <QString> void globalRegexMatch(const QString& text, const QString& pattern) { // 创建正则表达式对象 QRegularExpression re(pattern); // 检查正则有效性 if (!re.isValid()) { qDebug() << "Invalid regex:" << re.errorString(); return; } // 获取全局匹配迭代器 QRegularExpressionMatchIterator iter = re.globalMatch(text); // 遍历所有匹配结果 while (iter.hasNext()) { QRegularExpressionMatch match = iter.next(); qDebug() << "Found match:" << match.captured(0); // captured(0) 获取完整匹配 // 处理捕获组(可选) for (int i = 1; i <= match.lastCapturedIndex(); ++i) { qDebug() << "Capture group" << i << ":" << match.captured(i); } } } ``` ### 关键步骤说明 1. **创建正则对象**: ```cpp QRegularExpression re("\\b\\w+\\b"); // 示例:匹配单词 ``` 支持 Perl 兼容语法(PCRE),需注意转义(如 `\d` 需写为 `"\\d"`) 2. **全局匹配迭代**: ```cpp auto iter = re.globalMatch(text); // 返回匹配迭代器 ``` 替代已弃用的 `QRegExp::indexIn()` 3. **结果提取**: - `match.captured(0)`:完整匹配文本 - `match.captured(n)`:第 n 个捕获组(n≥1) - `match.capturedStart()`/`capturedEnd()`:匹配位置 ### 匹配选项(可选) ```cpp // 设置匹配选项(如忽略大小写) re.setPatternOptions(QRegularExpression::CaseInsensitiveOption); // 设置匹配类型(如贪婪/非贪婪) re.setPattern("a.+?b"); // 非贪婪匹配 ``` ### 示例调用 ```cpp QString text = "Qt 6.2 released in 2021, Qt 6.3 in 2022"; globalRegexMatch(text, "Qt (\\d+\\.\\d+)"); // 输出: // "Found match: Qt 6.2" // "Capture group 1: 6.2" // "Found match: Qt 6.3" // "Capture group 1: 6.3" ``` ### 注意事项 1. **转义处理**:C++ 字符串中需双重转义(如 `\d` → `"\\d"`) 2. **错误检查**:必须调用 `isValid()` 避免无效正则崩溃 3. **性能**:复杂正则匹配长文本时,考虑 `setPatternOptions(QRegularExpression::OptimizeOnFirstUsageOption)` 4. **Unicode**:默认支持 Unicode,使用 `\w` 匹配多语言字符 > 提示:Qt 5 开始推荐用 `QRegularExpression` 替代旧版 `QRegExp`,后者不支持全局迭代器且功能有限[^1]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值