英文:
Can regex identify characters interspersed with a limit?
问题
我是新手使用正则表达式,但我觉得我的模式可能太复杂了。
我正在寻找一个最小括号数和最大点数交替的模式。我看不到正则表达式如何计算整个模式中点的数量,而不是按顺序计算。
例如:
...((((((((.(((..((..((((.(((((((.(..(((((.(((.(((...))).))).)))))..)..))))))).))))..))..))).))))))))(((.((.(((((...((........))))))))))))............
如果我想要识别至少有25个(
的连续运行,并且从第一个(
到最后一个(
的点的数量最多为15个:
...<b>((((((((.(((..((..((((.(((((((.(..(((((.(((.(((</b>...))).))).)))))..)..))))))).))))..))..))).))))))))(((.((.(((((...((........))))))))))))............
我的正则表达式目前正在搜索最多连续15个.
的序列。
这是否可行?如果不行,我应该使用其他方法(例如pyparsing)。
到目前为止,这是我拥有的:
(\.{0,15}\(){25,}
英文:
I am new to using regex but I feel my pattern may be too complex.
I am looking for a pattern of a minimum number of brackets with a maximum number of dots interspersed. I can't see a way for regex to count the numbers of dots in the overall pattern instead of sequentially.
For example:
...((((((((.(((..((..((((.(((((((.(..(((((.(((.(((...))).))).)))))..)..))))))).))))..))..))).))))))))(((.((.(((((...((........))))))))))))............
If I want to identify a run of at least 25 (
s with a maximum of 15 .
s interspersed from the first (
to the last:
<pre>
...<b>((((((((.(((..((..((((.(((((((.(..(((((.(((.(((</b>...))).))).)))))..)..))))))).))))..))..))).))))))))(((.((.(((((...((........))))))))))))............
</pre>
My regex is currently searching for a a sequence with a maximum of 15 consecutive .
s instead.
Is this possible? If not should I be using an alternative (i.e. pyparsing)
This is what I have so far:
(\.{0,15}\(){25,}
答案1
得分: 2
根据 @Freeman 的想法,结合正则表达式和字符串操作:
import re
s = "...((((((((.(((..((..((((.(((((((.(..(((((.(((.(((...))).))).)))))..)..))))))).))))..))..))).))))))))(((.((.(((((...((........))))))))))))............"
pattern = r"\([\(.]+\"" # 这个模式以'('开头,以')'结束,只能包含'('和'.'。
matches = re.findall(pattern, s) # 找到所有符合模式的部分
for match in matches:
print(match)
print(f"'(' 的数量:{match.count('(')}") # 计算模式中每种字符的数量
print(f"'.' 的数量:{match.count('.')}")
输出:
((((((((.(((..((..((((.(((((((.(..(((((.(((.(((...))).))).)))))..)..))))))).))))..))..))).))))))))
('(' 的数量:36
'.' 的数量:11
(((.((.(((((...((........))))))))))))
('(' 的数量:12
'.' 的数量:5
通过这些计数,你可以根据特定的要求轻松筛选匹配项。
英文:
Based on @Freeman's idea combining regex and string operations:
import re
s = "...((((((((.(((..((..((((.(((((((.(..(((((.(((.(((...))).))).)))))..)..))))))).))))..))..))).))))))))(((.((.(((((...((........))))))))))))............"
pattern = r"\([\(.]+\(" # this pattern starts and ends with '(' and may only contain '(' and '.'
matches = re.findall(pattern, s) # find all such patterns
for match in matches:
print(match)
print(f"('s in match: {match.count('(')}") # count characters of each type in pattern
print(f".'s in match: {match.count('.')}") #
Output:
((((((((.(((..((..((((.(((((((.(..(((((.(((.(((
('s in match: 36
.'s in match: 11
(((.((.(((((...((
('s in match: 12
.'s in match: 5
With the counts you can easily filter out matches according to your specific requirements.
答案2
得分: 2
以下是翻译好的部分:
\(
匹配(
。(?!(?:\(*\.){16})
负向前瞻,断言当前位置的右侧不会有16个连续的点号,只允许在它们之间有可选的(
字符。(?:\.*\(){24,}
重复匹配24次或更多次,匹配可选的点号后跟匹配一个单独的(
。
如果要允许尾随的点号:
\((?!(?:\(*\.){16}\.*\()(?:\.*\(){24,}
英文:
You could use:
\((?!(?:\(*\.){16})(?:\.*\(){24,}
The pattern matches:
\(
Match(
(?!(?:\(*\.){16})
Negative lookahead, assert not 16 dots directly to the right of the current position, allowing only optional(
chars in between(?:\.*\(){24,}
Repeat 24 or more times matching optional dots followed by matching a single(
If you want to allow trailing dots:
\((?!(?:\(*\.){16}\.*\()(?:\.*\(){24,}
答案3
得分: 1
我认为你可以在Python中使用正则表达式和字符串操作的组合,例如这样:
import re
#示例数据
text = "...((((((((.(((..((..((((.(((((((.(..(((((.(((.(((...))).))).)))))..)..))))))).))))..))..))).))))))))(((.((.(((((...((........))))))))))))............"
#匹配外层括号之间的所有内容
pattern = r"\([^()]*\)"
#找到所有匹配的内容
matches = re.findall(pattern, text)
#遍历匹配项
for match in matches:
dot_count = match.count(".")
if dot_count <= 15:
print("Pattern matched!")
break
else:
print("Pattern not matched.")
输出:
Pattern matched!
英文:
I think you can use a combination of regex and string manipulation in python like this for example :
import re
#sample data
text = "...((((((((.(((..((..((((.(((((((.(..(((((.(((.(((...))).))).)))))..)..))))))).))))..))..))).))))))))(((.((.(((((...((........))))))))))))............"
#to match everything between the outer brackets
pattern = r"\([^()]*\)"
#find all matches of the pattern
matches = re.findall(pattern, text)
#iterate through the matches
for match in matches:
dot_count = match.count(".")
if dot_count <= 15:
print("Pattern matched!")
break
else:
print("Pattern not matched.")
Output:
Pattern matched!
答案4
得分: 1
以下是一个基于纯正则表达式的愚蠢方法,可以匹配所有12个时间,将“整个匹配”存储在第2组中:
\( # 匹配一个'('
(?= # 然后向前查看
(?:\.*\(){24} # 第25个括号
(.*) # 并捕获直到结尾的任何内容。
) #
(?<= # 回溯到第一个'('之前
(?= # 确保那里有
( #
\(* #
(?:\.\(*){0,15} # 从那里开始不超过15个点
) # 直到
$ # 我们捕获的第1组。
) #
\( #
) #
主要思想是使用系列中的最后一个括号作为限制,然后检查这两个括号之间的点数。实际上,回溯不是为了验证,而是为了捕获。
剩下的工作由.finditer()
来完成:
for match_no, match in enumerate(regex.finditer(text), 1):
print(f'{match_no = }')
print(f'index = {match.start(0)}')
print(f'{match[2] = !r}\n')
试试看:
match_no = 1
index = 3
match[2] = '((((((((.(((..((..((((.(((((((.(&';
...
match_no = 12
index = 17
match[2] = '((..((((.(((((((.(..(((((.(((.(((&';
英文:
Here's a stupid pure regex approach that matches all 12 times, with "the whole match" stored in group 2:
\( # Match a '('
(?= # then lookahead to
(?:\.*\(){24} # the 25th bracket
(.*) # and capture anything after that until the end.
) #
(?<= # Take a step back behind the first '('
(?= # then assure that there are
( #
\(* #
(?:\.\(*){0,15} # no more than 15 dots from there
) # until
$ # the group 1 we captured.
) #
\( #
) #
Try it on regex101.com.
The main idea is to use the last bracket in the series as the limit, then check the number of dots between those two. The lookbehind is actually not needed for verifying, only for capturing.
The rest is the job of .finditer()
:
for match_no, match in enumerate(regex.finditer(text), 1):
print(f'{match_no = }')
print(f'index = {match.start(0)}')
print(f'{match[2] = !r}\n')
Try it:
match_no = 1
index = 3
match[2] = '((((((((.(((..((..((((.(((((((.('
...
match_no = 12
index = 17
match[2] = '((..((((.(((((((.(..(((((.(((.((('
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论