Regex多行字符串单个匹配组



在我开始之前,我知道已经有很多关于这个主题的线程创建了,但我找不到任何特定于我的用例的东西,因此我想根据我的发现用一个实际的例子来问这个问题。

我有一个多行字符串,其中包含我感兴趣的内容:

hello: "
-foo=value1
-bar=value2
-baz="value3"
"

我想在多行字符串中的特定内容上匹配group,这样它就可以在这个字符串中以-开头的任何内容上匹配。条件是:

  • 必须以单词hello:开头
  • 对字符串中以-开头的每个值进行匹配分组
  • 将转义引号视为字符串的一部分:"
  • 字符串也可以作为一个liner,并进行相同的匹配:hello: "-foo=value1"

我想出了这个模式:

hello:s*"s*-((?:[^"]|n)*)"

不幸的是,它不考虑转义字符串,也不匹配每个结果。我需要匹配的组在该字符串中的每一行上重复。

您可以使用

hello:s*"(?:s*-((?:\.|[^n"\])+))+s*"

请在.NET正则表达式测试仪上查看此正则表达式演示详细信息

  • hello:s*"-hello:,零个或多个空白,"
  • (?:s*-((?:\.|[^n"\])+))+-出现一次或多次:
    • s*-零次或多次出现空白字符,然后是-
    • ((?:\.|[^n"\])+)-组1:出现一个或多个转义字符或除"和换行符之外的任何字符
  • CCD_ 15-零个或多个空白,然后是CCD_ 16

查看此C#演示:

var s = "hello: "n  -foo=value1n  -bar=value2n  -baz=\"value3\"n"";
var rx = @"hello:s*""(?:s*-((?:\.|[^n""\])+))+s*""";
var result = Regex.Match(s, rx)?.Groups[1].Captures.Cast<Capture>().Select(x => x.Value).ToList();
foreach (var t in result)
Console.WriteLine(t);

请参阅此Python演示:

import regex
s = 'hello: "n  -foo=value1n  -bar=value2n  -baz=\"value3\"n"';
rx = r'hello:s*"(?:s*-((?:\.|[^n"\])+))+s*"';
match = regex.search(rx, s)
if match:
print(match.captures(1))

输出:

foo=value1
bar=value2
baz="value3"

这种方法在围棋中不起作用。您需要使用hello:s*"([^"\]*(?:\[sS][^"\]*)*)"提取整个匹配,然后使用换行序列拆分Group 1值。

我尝试了一种递归方法来解决这个问题。这是我的解决方案。

我把它作为我的输入文本块,我想它已经捕捉到了所有的可能性:

source_text = """
hello: "
-foo=value1
-bar=value2
-baz="value3"
"
bla: "
-foo=value1
-bar=value2
-baz="value3"
"
hello: "
-foo=value1
-bar=value2
-baz="value3"
"
hello: -baz="value3"
hello: "-foo=value1"
"""

递归匹配正则表达式hello:s("|\")?n?(s*-w+=\?"?w+\?"?n?)+,该正则表达式捕获match group 2中所需的文本

import re
all_matches = []
def get_all_matches(text):
for block_match in re.finditer(r'hello:s("|\")?n?(s*-w+=\?"?w+\?"?n?)+', text):
match = block_match.group(2)
if match:
all_matches.append(re.sub("n|\s", '', match))
full_match = block_match.group(0)
get_all_matches(full_match.replace(match, ''))
get_all_matches(source_text)

输出

print(all_matches)
['-baz="value3"', '-bar=value2', '-foo=value1', '-baz="value3"', '-bar=value2', '-foo=value1', '-baz="value3"', '-foo=value1"']

最新更新