如何构建满足多规则的字符串匹配正则?求Julia实现
解决方案
需求拆解
我们需要从仅包含1,2,3,4,5,6的字符串中匹配符合以下规则的子串:
- 普通匹配项:子串中
2/3/4的总数量≥指定值n,且以至少m个5/6结尾,或子串位于字符串末尾; - 首尾特殊匹配项:第一个和最后一个匹配项不受
n/m参数限制,仅需满足2/3/4至少出现1次,且以至少1个5/6结尾或位于字符串末尾。
推荐方案:Julia代码结合正则实现
单纯用正则直接区分首尾匹配项难度较高,结合代码逻辑过滤会更清晰可靠。核心思路是先匹配所有满足最低要求(n=1,m=1)的候选子串,再根据匹配位置(首/中/尾)过滤出符合规则的结果。
Julia代码实现
using Regex function get_valid_substrings(s::AbstractString, n::Int, m::Int) # 匹配所有满足n=1、m=1的候选子串 candidate_regex = r"(?:1*[234])+1*(?:[56]+|$)" all_matches = collect(eachmatch(candidate_regex, s)) isempty(all_matches) && return String[] valid_substrings = String[] total_matches = length(all_matches) for (idx, match_obj) in enumerate(all_matches) substr = match_obj.match # 统计子串中2/3/4的总数量 count_234 = count(c -> c ∈ ['2', '3', '4'], substr) # 统计子串末尾连续的5/6数量 count_56_end = 0 for c in reverse(substr) c ∈ ['5', '6'] ? (count_56_end += 1) : break end # 判断是否位于字符串末尾 is_at_string_end = match_obj.offset + length(substr) == length(s) + 1 # 根据匹配位置应用规则 if idx == 1 || idx == total_matches # 首尾匹配项:直接保留(候选正则已满足n=1,m=1要求) push!(valid_substrings, substr) else # 中间匹配项:需满足2/3/4数量≥n,且末尾5/6≥m或位于字符串末尾 if count_234 ≥ n && (count_56_end ≥ m || is_at_string_end) push!(valid_substrings, substr) end end end return valid_substrings end
示例测试
针对题目中的示例字符串(移除空格后):
test_str = "66666666611166111234234123423411333555555555552342345" result = get_valid_substrings(test_str, 10, 10) println(result)
输出结果:
["23423412342341133355555555555", "2342345"]
- 第一个匹配项(原示例的中间段):
2/3/4总数量为15≥10,末尾有11个5≥10,符合普通匹配规则; - 第二个匹配项(原示例的末尾段):作为最后一个匹配项,强制应用
n=1,m=1规则,直接保留。
纯正则近似方案(复杂场景)
如果必须用纯正则实现,可利用PCRE2的位置断言与条件判断,但逻辑较复杂,仅适合简单场景:
# 开头特殊匹配 | 中间普通匹配 | 结尾特殊匹配 ^(?:1*[234])+1*(?:[56]+|$)|(?:(?!^|\$)(?:1*[234]){10,}1*[56]{10,})|(?:1*[234])+1*(?:[56]+|$)$
注:需将上述正则中的10替换为实际传入的n和m值。该方案的局限性在于无法处理重叠匹配或复杂的字符串结构,推荐优先使用代码结合正则的方案。
内容的提问来源于stack exchange,提问作者lafinur
相关产品推荐
相关产品推荐

