JS中正则表达式

 JS中正则表达式有几种不同的使用方法,一些用法是通过字符串对象来使用,另外一些通过正则表达式对象使用。

一、RegExp(正则表达式)的属性和方法

1、属性
RegExp的实例有几个只读的属性:
global表示是否为全局匹配,
igoreCase表示是否忽略大小写,
multiline表示是否为多行匹配,
source是正则式的源文本,如/[ab]/g的源文本就是[ab];

另外还有一个可写的属性是lastIndex,表示下次执行匹配时的起始位置。
2、方法
RegExp有两个方法exec和test,均以待匹配的字符串为参数。

(1)exec
如果没有发现匹配则返回null,否则返回一个数组,该数组的第一项为匹配的字符串,接下去为与各个子表达式相匹配的子串;该数组的属性index表示发生匹配的位置,属性input表示被检索的字符串。
注意:如果正则式具有全局属性g,则执行一次exec后,该RegExp对象的lastIndex属性会被设为紧接着匹配子串的字符位置,当该RegExp对象再次调用exec时就会从lastIndex处开始执行匹配。如果exec没有发现任何匹配,它会将lastIndex设为0。当然,如果没有全局属性g的话,exec总是会将lastIndex设为0。
例如:
re = /[ab]+(c)+/g;
m = re.exec('acabcc');
// m[0]为'a', m[1]为'c', m.index为0,m.input为'acabcc',re.lastIndex为2
m = re.exec('acabcc');
// m[0]为'ab', m[1]为'cc', m.index为2,m.input为'acabcc',re.lastIndex为6
m = re.exec('acabcc');
// m为null,re.lastIndex为0

(2)test
test方法执行一次exec,如果发生匹配返回true,否则返回false。
因为test方法是调用exec的,所以也可以用test方法来遍历一个字符串。


二、和正则式相关的几个String(字符串)的方法
1、search(RegExp)
返回第一个与之匹配的子串的开始位置,如果没有匹配则返回-1。
传入的参数如果不是正则式则会传递给RegExp构造函数先转成正则式再进行匹配.
不支持全局匹配g
2、replace(RegExp, replacement)
第一个参数是正则式,第二个参数是要进行替换的字符串。
如果正则式指定了全局模式g,则会替换所有的匹配,否则只替换第一个匹配。replacement中的$符号具有特殊含义,$1,$2,...,$99 代表与正则式中的第1个到第99个子表达式相匹配的文本,$& 代表与正则式相匹配的文本,$` 代表位于匹配字串左侧的文本,$' 代表位于匹配字串右侧的文本,$$ 为直接量$
例如,想用花引号代替直引号,可用如下代码:
text.replace(/"([^"])*"/g, "``$1''")
另外,replacement也可是函数,传入的参数就是匹配的文本,返回替换的文本即可。
例如,将文本中每个单词的首字母改为大写字母:
text.replace(//b/w+/b/g, function(word){return word.substr(0,1).toUpperCase()+word.substr(1);})
3、match(RegExp)
无匹配时返回null, 否则返回一个数组,该数组的内容取决于正则式是否具备全局属性g。如果没有全局属性g,则match的返回值和exec的返回值类似。如果具有全局属性g,则返回数组代表的是所有匹配的文本,而不含有任何子表达式匹配的信息,也没有index和input属性
4、split(delimiter, limit)
返回一个字符串数组,这些数组元素是通过从头到尾检索字符串中与delimiter相匹配的文本,在文本之前和之后分割原string得到,返回的子串中不包括定界符文本(注:当delimiter是包含子表达式的正则式时,返回数组中将包含与子表达式相匹配的文本,但是不包含与整个正则式相匹配的文本)。如果定界符与字符串的开头相匹配,则返回数组的第一个元素是空串;如果定界符与字符串结尾相匹配,则数组的最后一个元素是空串(注:如果delimiter是空串或与空串相匹配的正则式,那么字符串的每个字符之间都被分割,返回数组长度与原字符串长度一致,因为空串不匹配字符串的开头或结尾!
例如:"Hello<b>world</b>".split(/(<[^>]*>)/)
返回 ['Hello ', '<b>', 'world', '</b>', ''])。
<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("复杂匹配失败"); } ``` ###
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值