如何让Python的re.search匹配#与$字符以提取目标子串?
问题描述
我尝试用Python的re模块提取两个标记之间的子串,示例代码如下:
import re test_str = "#$ -N model_simulation 2022" # 以下两行可正常运行,输出为:model_simulation print(re.search("-N(.*)2022",test_str).group(1)) print(re.search(" -N(.*)2022",test_str).group(1)) # 以下两行报错:'NoneType' object has no attribute 'group' print(re.search("$ -N(.*)2022",test_str).group(1)) print(re.search("#$ -N(.*)2022",test_str).group(1))
实际业务场景中-N并非唯一标记,必须通过#和$来定位目标内容,但直接在正则里写#$会匹配失败,请问如何让re强制匹配这两个字符,或者有无不使用re的替代方案?
解决方案
一、正则表达式解决方案
问题出在$是正则的特殊元字符,代表字符串的结束位置,直接写$会被解析成结束符而非字面的$字符。要匹配字面的$,需要用\$进行转义;#在正则中不是特殊字符,无需转义。结合转义后的写法即可正确匹配开头的#$。
修改后的代码如下:
import re test_str = "#$ -N model_simulation 2022" # 匹配#$开头的目标内容 result = re.search(r"#\$ -N(.*)2022", test_str) if result: print(result.group(1).strip()) # 输出: model_simulation
- 使用
r""原始字符串写法,避免转义字符被Python字符串解析,让正则引擎直接处理\$ - 调用
strip()去除结果前后空格,输出更整洁 - 先判断
result不为None再调用group(),避免触发属性错误
二、非正则替代方案
如果不想使用正则,可以通过字符串的find()方法定位标记位置,直接截取子串:
test_str = "#$ -N model_simulation 2022" # 定义起始和结束标记 start_mark = "#$ -N " end_mark = " 2022" # 计算截取的起始和结束索引 start_idx = test_str.find(start_mark) + len(start_mark) end_idx = test_str.find(end_mark, start_idx) if start_idx != -1 and end_idx != -1: print(test_str[start_idx:end_idx]) # 输出: model_simulation
这种方法逻辑直观,无需处理正则元字符问题,适合标记固定的场景。
内容的提问来源于stack exchange,提问作者Jeremy
相关产品推荐
相关产品推荐

