如何用正则表达式在Bash/Sed/Python中匹配无重复字母子串?
查找指定长度无重复字母子串的正则实现
针对你提出的需求(从字符串中找出指定长度、所有字符均不重复的子串),以下是Bash、Sed、Python中的正则实现方案,以查找长度为4的子串为例,你可根据需要替换长度值:
Bash(GNU Grep)
利用GNU Grep的Perl兼容正则(PCRE)特性,通过反向引用+负向预查实现:
echo "asbshbsbuhb" | grep -oP '(?=(.)(?!.*\1)(.)(?!.*\2)(.)(?!.*\3)(.))\1\2\3\4'
-o:仅输出匹配的子串-P:启用PCRE语法- 正则逻辑:通过正向预查定位起始位置,确保后续4个字符中每个字符都未在之前出现过(
(?!.*\1)表示当前字符不会在后续位置重复),最后捕获并输出这4个字符。若要调整长度,比如找长度3的子串,只需修改为(?=(.)(?!.*\1)(.)(?!.*\2)(.))\1\2\3。
Sed(GNU Sed 4.2+)
GNU Sed 4.2及以上版本支持PCRE,可使用类似逻辑:
echo "asbshbsbuhb" | sed -n -P 's/.*(?=(.)(?!.*\1)(.)(?!.*\2)(.)(?!.*\3)(.))/\1\2\3\4/p'
-n:禁止自动输出模式空间内容-P:启用PCRE语法- 正则通过匹配整个字符串,定位符合条件的子串后替换输出。同样可通过调整正则中的字符组数来修改目标子串长度。
Python
借助re模块动态构造正则表达式,适配任意指定长度:
import re target_str = "asbshbsbuhb" substring_length = 4 # 动态生成正则模式 pattern_parts = [r'(.)(?!.*\1)'] * (substring_length - 1) pattern_parts.append(r'(.)') pattern = r'(?=(' + ''.join(pattern_parts) + r'))\1' matches = re.findall(pattern, target_str) # 将匹配到的元组拼接为字符串 result = [''.join(match) for match in matches] print(result) # 输出: ['sbuh']
- 代码会根据指定长度自动生成对应数量的反向引用和负向预查规则,确保子串内所有字符唯一。若需调整长度,修改
substring_length的值即可。
内容的提问来源于stack exchange,提问作者tjzel
相关产品推荐
相关产品推荐

