如何匹配、计数、替换含空格且不属于其他字母字符串子串的字符串
实现思路
核心通过正则的零宽断言限制匹配字符串s1的前后不能出现任意语言的字母字符,其他字符(包括emoji、表情符号、标点、空格、数字等)都不限制,完全匹配你的规则要求。
正则规则说明
- 前缀断言
(?<!\p{L}):限制s1前面的位置不能是任意字母(\p{L}是Unicode字符属性,代表所有语言的字母类字符,覆盖中英日韩等所有语言的字母) - 中间部分:需要转义后的
s1,避免s1包含正则特殊字符(比如. * + ?等)导致匹配异常 - 后缀断言
(?!\p{L}):限制s1后面的位置不能是任意字母 - 匹配时需要开启Unicode模式让
\p{L}生效,同时开启全局匹配统计所有命中项
Python 实现示例
import re def count_s1_occurrence(s1: str, s2: str) -> int: # 转义s1中的正则特殊字符 escaped_s1 = re.escape(s1) # 构造正则,开启Unicode模式 pattern = re.compile(rf'(?<!\p{L}){escaped_s1}(?!\p{L})', re.UNICODE) # 查找所有匹配项返回数量 return len(pattern.findall(s2)) # 测试验证 s1 = "bad word" # 正向测试用例(预期命中) test_positive = [ "bad word", "This is a bad word.", "This are bad word bad word.", "bad word:(", "bad word😠", "bad word bad word😠😠" ] for case in test_positive: print(f"'{case}' 命中次数:{count_s1_occurrence(s1, case)}") # 输出依次为1、1、2、1、1、2,完全符合预期 # 反向测试用例(预期不命中) test_negative = [ "This isbad word", "bad wordsdsdsd", "bad wordbad word" ] for case in test_negative: print(f"'{case}' 命中次数:{count_s1_occurrence(s1, case)}") # 全部输出0,完全符合预期
JavaScript 实现示例
function countS1Occurrence(s1, s2) { // 转义s1中的正则特殊字符 const escapedS1 = s1.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // 构造正则,u开启Unicode模式,g开启全局匹配 const pattern = new RegExp(`(?<!\\p{L})${escapedS1}(?!\\p{L})`, 'gu'); // 匹配所有结果返回数量 return (s2.match(pattern) || []).length; } // 测试逻辑和Python示例完全一致,返回结果相同
注意:零宽负向后行断言需要Python 3.7+、Node.js 10+、Chrome 62+等支持ES2018+的运行环境,当前绝大多数主流生产环境都可正常使用。
内容的提问来源于stack exchange,提问作者hafiz031
相关产品推荐
相关产品推荐

