从两行获取字符串的正则表达式模式
Posted
技术标签:
【中文标题】从两行获取字符串的正则表达式模式【英文标题】:Regex Pattern that gets string from two line 【发布时间】:2021-12-03 15:44:00 【问题描述】:我已经创建并测试了这个 Regexpattern <\w\w:Value> SYMBOL: (P.*)=(.*)\/\/(.*)
Regex regexPattern = new Regex(@"<\w\w:Value> SYMBOL: (P.*)=(.*)\/\/(.*)");
var attributeChecker = regexPattern.Match(line);
var attributeLongDescription = attributeChecker.Groups[3].ToString().Trim();
这是模型:
<AC:Value> SYMBOL: PDWFNA = 0; // Projektierung D-Weg Freimeldung nicht
// auswerten
<AC:Value> SYMBOL: PDWLE = 0; // Länge des Durchrutschweges
我从第三组得到的结果是:
Projektierung D-Weg Freimeldung nicht
Länge des Durchrutschweges
如何从第三组获得这些结果:
Projektierung D-Weg Freimeldung nicht auswerten
Länge des Durchrutschweges
【问题讨论】:
您不能这样做,您需要匹配模式匹配下方所有作为注释延续的行,然后对结果进行后处理。 @WiktorStribiżew 你能给我举个例子吗,我该怎么做? 我正在编写代码,但您已经得到了答案。 @WiktorStribiżew 如果你有更好的答案,你可以发布你的,我会删除我的。 @AdrianHHH 现在,问题是 1)不同,2)不清楚,因为没有输入文本,没有样本来测试模式。 kn1ghtx,请保持问题原样,如果当前解决方案只有一点问题,请在答案下方发表评论,如果问题更大,请考虑提出新问题。暂时回滚到最新的正常问题。 【参考方案1】:您不能将字符串的不相交部分捕获到单个捕获组中。您需要匹配模式匹配下方所有作为注释延续的行,然后对结果进行后处理。
您可以使用以下方法(参见C# demo):
var text = @"<AC:Value> SYMBOL: PDWFNA = 0; // Projektierung D-Weg Freimeldung nicht
// auswerten
<AC:Value> SYMBOL: PDWLE = 0; // Länge des Durchrutschweges";
var matches = Regex.Matches(text, @"<\w2:Value> SYMBOL: (P.*)=(.*)//(.*(?:\n[\s-[\r\n]]*//.*)*)");
foreach (Match m in matches)
Console.WriteLine("--- A new match ---");
Console.WriteLine($"Group 1: m.Groups[1].Value");
Console.WriteLine($"Group 2: m.Groups[2].Value");
Console.WriteLine("Group 3: 0",
string.Join(" ",
m.Groups[3].Value.Split(new[] "//", StringSplitOptions.RemoveEmptyEntries)
.Select(x => x.Trim())
)
);
输出:
--- A new match ---
Group 1: PDWFNA
Group 2: 0;
Group 3: Projektierung D-Weg Freimeldung nicht auswerten
--- A new match ---
Group 1: PDWLE
Group 2: 0;
Group 3: Länge des Durchrutschweges
另请参阅regex demo。
(.*(?:\n[\s-[\r\n]]*//.*)*)
部分使用.*
将当前行的其余部分捕获到第 3 组,然后是任何零个或多个可以以 CR 和 LF 以外的零个或多个空格开头的行,然后是 //
,然后直到行尾的任何内容。
string.Join(" ", m.Groups[3].Value.Split(new[] "//", StringSplitOptions.RemoveEmptyEntries).Select(x => x.Trim()))
是对第 3 组值进行后处理的一种方式。在这里,它被//
子字符串分割,然后所有生成的项目都从前导/尾随空格中删除,然后将它们连接成一个带有空格的字符串。
您也可以使用Regex.Replace(m.Groups[3].Value, @"\s*//\s*", " ")
来缩短它。
【讨论】:
仅供参考:如果注释行之间可以包含空白行,请将[\s-[\r\n]]
替换为 \s
。
很好,[\s-[\r\n]]
和 [\pZs\t]
一样吗?
@Thefourthbird [\s-[\r\n]]
更等于 [^\S\r\n]
。 [\pZs\t]
更具体。
@kn1ghtx 你可能想排除后面有aterisks的cmets,试试<\w2:Value> SYMBOL: (P.*)=(.*)//(?!\s*\*)(.*(?:\n[\s-[\r\n]]*//(?!\s*\*).*)*)
@kn1ghtx 当然不是。正则表达式模式中的\n
需要找到一个LF char,当你逐行读取时,输入中没有LF。【参考方案2】:
匹配后可以处理第3组的匹配,去掉前导换行符、空格和//
<\w\w:Value> SYMBOL: (P[^=\n]*)=(.*?)//(.*(?:\n[\pZs\t]*//.*)*)
模式匹配:
<\w\w:Value> SYMBOL:
字面匹配
(P[^=\n]*)
捕获组 1,匹配 P
后跟不是 =
或换行符
=
字面匹配
(.*?)
捕获组 2,匹配除换行符以外的任何字符,非贪婪
//
字面上匹配
(
捕获第 3 组
.*
匹配该行的其余部分
(?:
非捕获组
\n[\pZs\t]*//.*
匹配换行符、可选空格和 // 以及该行的其余部分
)*
关闭
)
关闭第三组
.NET regex demo | C# demo
例如,替换后只打印第 3 组:
string pattern = @"<\w\w:Value> SYMBOL: (P[^=\n]*)=(.*?)//(.*(?:\n[\pZs\t]*//.*)*)";
string input = @"<AC:Value> SYMBOL: PDWFNA = 0; // Projektierung D-Weg Freimeldung nicht
// auswerten
<AC:Value> SYMBOL: PDWLE = 0; // Länge des Durchrutschweges";
foreach (Match match in Regex.Matches(input, pattern))
Console.WriteLine(Regex.Replace(match.Groups[3].Value, @"\r?\n[\pZs\t]+//",""));
输出
Projektierung D-Weg Freimeldung nicht auswerten
Länge des Durchrutschweges
【讨论】:
\r?
是不必要的,.
已经匹配 CR 符号。 //
也可以从行首开始。
谢谢,但是我得到的是// Projektierung D-Weg Freimeldung nicht // auswerten
而不是Projektierung D-Weg Freimeldung nicht auswerten
以上是关于从两行获取字符串的正则表达式模式的主要内容,如果未能解决你的问题,请参考以下文章