js中正则表达式的易错点

1. 匹配符部分匹配规则
  • js的正则表达式总是匹配第一个满足匹配的,比如下面这个例子
	var str = "aaab";
	var pattern = /a+?b/;
	console.log(pattern.exec(str));
  • 程序输出:“aaab”

  • 虽然上面加了问号是非贪婪匹配,但是正则表达式的字符匹配是从满足条件的第一个字符开始匹配的,故从第一个a开始匹配,又因为一定要和最后一个b进行匹配,故前面三个a必须全都要进行匹配。

  • 操作符只能影响前面的一个字符,并不能影响前面的多个字符。

 	 var str = "angel";
 	 var pattern = /e?el?/;
  	 console.log(pattern.exec(str));
  • 程序输出:“el”
  • 虽然是从正则表达式中第一个满足的进行匹配,但是最后面有一个l,e?匹配成功后后面的l就没法匹配成功了,故第一个e?并没有进行匹配。故最终返回“el”。
2. 分组匹配规则:
	var str  = "ab";
	var pattern = /a|ab/;
	console.log(pattern.exec(str));
  • 程序输出:“a”
  • 将分组中从左到右按顺序和str中字符串进行匹配,一旦匹配上就不再将分组中的其它字符和str进行匹配,故此程序中分组中的ab都没有得到机会和str中的字符串进行匹配。
3. 注意^的不同用法
	var pattern1 = /[^0-9]/ //在字符类中的‘^’号表示非的意思,此代码中的意思就是表示非数字
	var pattern2 = /^js/ //这里表示的是首匹配,也就是要匹配的字符串前两个字母必须是js才能匹配成功,若str = “ja”,则也匹配不成功返回null
4. 不要忘记转义
  • 在使用构造函数声明正则表达式时,在RegExp()中传入参数时,如果用到\一定不要忘记进行转义,如下面的代码所示:
var pattern =new RegExp("\\b"+"str"+"\\b") ; 
// "\\b"+"str"+"\\b" === /\bstr\b/
var pattern1 =new RegExp("\b"+"str"+"\b") ; 
// "\b"+"str"+"\b" === / str /

5. 正则表达式对象中lastIndex属性
  • 开始时lastIndex的值为0,利用全局匹配时,每当我们执行一次pattern.exec(str);lastIndex的值会增加到当前匹配完后的字符的下一个位置,一直增加。当我们最后匹配结束返回null时,lastIndex的值变为0.
  • 非全局匹配时,lastIndex的值永远是0.
  • 代码如下:
	var str = "js js js js";
    var pattern = /js/g;
    console.log("lastIndex = "+pattern.lastIndex);
    console.log(pattern.exec(str));
    console.log("lastIndex = "+pattern.lastIndex);
    console.log(pattern.exec(str));
    console.log("lastIndex = "+pattern.lastIndex);
    console.log(pattern.exec(str));
    console.log("lastIndex = "+pattern.lastIndex);
    console.log(pattern.exec(str));
    console.log("lastIndex = "+pattern.lastIndex);
    console.log(pattern.exec(str));
    console.log("lastIndex = "+pattern.lastIndex);
  • 运行结果:
    在这里插入图片描述
6. exec VS match
  • exec是正则表达式实例的方法,match是字符串对象的方法
  • exec: 无论是否是全局匹配都会返回分组中匹配到的内容,在全局匹配中,匹配到的内容只会返回当前匹配的内容,而不会全部返回.
  • match:只有在非全局匹配时才会返回分组中的内容,在全局匹配中会将匹配到的内容全部返回。
  • 示例代码:
var str = "js js js";
    var pattern = /(j)s/g;
    console.log("全局匹配match得到的内容:");
    console.log(str.match(pattern));
    console.log("全局匹配exec得到的内容:");
    console.log(pattern.exec(str));
  • 运行结果:
    在这里插入图片描述

  • 更新中,如有错误欢迎指正…

<think>我们正在处理一个字符串:"DFGPO,(PTC5,PTC4,PTC3,PTC2),(gTESTPORT_DATA)"目标:匹配该行,然后将第二个括号内的内容(即"gTESTPORT_DATA")作为键,第一个括号内的内容(即"PTC5,PTC4,PTC3,PTC2")作为值。注意:之前版本的正则表达式可能没有正确匹配,因此我们需要调整。分析字符串结构:-以"DFGP"开头-然后是一个单词(这里是"O"),后面紧跟一个逗号-然后是第一组括号,里面包含逗号分隔的内容(没有括号嵌套)-然后是逗号-然后是第二组括号,里面是键(没有逗号,但实际可能有?题目中是单个标识符)我们设计正则表达式:/DFGP\s+(\w+)\s*,\s*\(([^()]*)\)\s*,\s*\(([^()]*)\)/解释:-`DFGP\s+`:匹配"DFGP"和至少一个空白(空格或制表等)-`(\w+)`:匹配一个单词(这里是"O"),并捕获-`\s*,\s*`:匹配逗号,前后可能有空白-`\(([^()]*)\)`:匹配第一个括号,括号内不能有括号(因为题目没有嵌套),我们使用`[^()]*`匹配任意非括号字符-同理匹配第二个括号但是,我们不需要捕获中间的那个单词(即"O"),题目要求只取两个括号的内容。而且题目要求第二个括号作为键,第一个括号作为值。修正正则:我们只关心两个括号内的内容,所以可以这样写:/DFGP\s+\w+\s*,\s*\(([^()]*)\)\s*,\s*\(([^()]*)\)/这里:-第一个括号内的内容由第一个捕获组`([^()]*)`匹配-第二个括号内的内容由第二个捕获组`([^()]*)`匹配注意:如果括号内允许空格,我们这里没有排除空格,所以是可以的。但是,我们观察到输入字符串中第一个括号前有一个空格?实际上,在逗号后面没有空格,但正则中我们用了`\s*`可以匹配0个或多个空格。测试一下:输入:"DFGPO,(PTC5,PTC4,PTC3,PTC2),(gTESTPORT_DATA)"匹配:-"DFGPO"->匹配"DFGP"+空格+"O"-逗号:匹配","-第一个括号:匹配"(PTC5,PTC4,PTC3,PTC2)",捕获组1得到"PTC5,PTC4,PTC3,PTC2"-逗号:匹配","-第二个括号:匹配"(gTESTPORT_DATA)",捕获组2得到"gTESTPORT_DATA"这样,我们就能将捕获组2作为键,捕获组1作为值。代码实现:注意:如果一行中有多个这样的结构,我们需要用全局匹配,但题目是一行一个。下面给出代码:</think>### JavaScript 正则表达式解决方案 在 JavaScript 中,正则表达式是处理字符串匹配和提取的强大工具。以下是一个完整的解决方案,用于匹配指定行并提取键值对: ```javascript // 输入字符串 const input = "DFGP O,(PTC5,PTC4,PTC3,PTC2),(gTESTPORT_DATA)"; // 优化后的正则表达式 const regex = /DFGP\s+\w+\s*,\s*\(([^)]+)\)\s*,\s*\(([^)]+)\)/; // 执行匹配 const match = input.match(regex); if (match) { // 提取值(第一个括号内容) const value = match[1]; // 提取键(第二个括号内容) const key = match[2]; // 创建结果对象 const result = { [key]: value }; console.log("匹配成功!"); console.log("结果对象:", result); // 输出: { gTESTPORT_DATA: 'PTC5,PTC4,PTC3,PTC2' } } else { console.log("未找到匹配项"); } ``` ### 正则表达式详解 ```regex /DFGP\s+\w+\s*,\s*\(([^)]+)\)\s*,\s*\(([^)]+)\)/ ``` 1. **DFGP** - 匹配字面字符串 "DFGP" 2. **\s+** - 匹配一个或多个空白字符(空格、制表符等) 3. **\w+** - 匹配一个或多个单词字符(字母、数字或下划线) 4. **\s*,\s*** - 匹配逗号,允许前后有任意空白 5. **\(([^)]+)\)** - 匹配括号及其内容: - **\(** - 转义左括号 - **([^)]+)** - 捕获组1:匹配一个或多个非右括号的字符 - **\)** - 转义右括号 6. **\s*,\s*** - 匹配逗号,允许前后有任意空白 7. **\(([^)]+)\)** - 匹配第二个括号及其内容(捕获组2) ### 处理多个匹配项 ```javascript const multiInput = ` DFGP O,(PTC5,PTC4,PTC3,PTC2),(gTESTPORT_DATA) DFGP I,(PTB3,PTB2,PTB1,PTB0),(gTESTPORT_ADDR) DFGP X,(A1,A2,A3),(gANOTHER_PORT) `; const regexGlobal = /DFGP\s+\w+\s*,\s*\(([^)]+)\)\s*,\s*\(([^)]+)\)/g; const resultMap = new Map(); let match; while ((match = regexGlobal.exec(multiInput)) !== null) { const value = match[1]; const key = match[2]; resultMap.set(key, value); } console.log("提取的多个键值对:"); console.log([...resultMap.entries()]); /* 输出: [ ["gTESTPORT_DATA", "PTC5,PTC4,PTC3,PTC2"], ["gTESTPORT_ADDR", "PTB3,PTB2,PTB1,PTB0"], ["gANOTHER_PORT", "A1,A2,A3"] ] */ ``` ### 正则表达式调试技巧 如果正则表达式不工作,可以使用以下方法调试: 1. **使用在线工具**: - [Regex101](https://regex101.com/) - [RegExr](https://regexr.com/) 2. **逐步分解正则**: ```javascript // 测试正则的各部分 const parts = [ /DFGP/, // 匹配 "DFGP" /\s+/, // 匹配空白 /\w+/, // 匹配标识符 /\s*,\s*/, // 匹配逗号 /\(([^)]+)\)/, // 匹配第一个括号内容 /\s*,\s*/, // 匹配逗号 /\(([^)]+)\)/ // 匹配第二个括号内容 ]; // 测试每个部分是否匹配 parts.forEach((part, i) => { const test = input.match(part); console.log(`部分 ${i+1}:`, test ? "匹配成功" : "匹配失败", part.toString()); }); ``` ### 处理复杂情况的增强版 ```javascript // 支持括号内可能包含逗号但不包含嵌套括号的情况 const complexInput = "DFGP O,(PTC5, PTC4, 'test,value', PTC2),(gTESTPORT_DATA)"; // 增强版正则:允许括号内包含逗号但不包含右括号 const complexRegex = /DFGP\s+\w+\s*,\s*\(([^)]+)\)\s*,\s*\(([^)]+)\)/; const complexMatch = complexInput.match(complexRegex); if (complexMatch) { const value = complexMatch[1]; const key = complexMatch[2]; console.log("复杂匹配成功:", { [key]: value }); // 输出: { gTESTPORT_DATA: "PTC5, PTC4, 'test,value', PTC2" } } else { console.log("复杂匹配失败"); } ``` ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值