Backus-Naur 形式的正则表达式
Regex for Backus-Naur Form
我正在尝试制作一个正则表达式来匹配如下字符串:
i<A> | n<B> | <C>
它需要 return 值:
- ("我", "A")
- ("n", "B")
- ("", "C")
目前我正在使用以下正则表达式:
^([A-Za-z0-9]*)\<(.*?)\>
但它只匹配第一对 ("i", "A")。
我找不到修复它的方法。
^ 断言行首的位置,因此如果您删除 i 应该工作,它只会检查每行的开头
并添加一个?对于空值,请参见下面的示例
string pattern = @"([A-Za-z0-9]?)<(.?)>";
string input = @"i<A> | n<B> | <C>";
RegexOptions options = RegexOptions.Multiline;
foreach (Match m in Regex.Matches(input, pattern, options))
{
Console.WriteLine("'{0}' found at index {1}.", m.Value, m.Index);
}
如果 |
是字符串的一部分并且应该被匹配,您可以使用 captures property 和 2 个同名的捕获组。
^(?<first>[A-Za-z0-9]*)<(?<second>[^<>]*)>(?:\s+\|\s+(?<first>[A-Za-z0-9]*)<(?<second>[^<>]*)>)+$
模式匹配:
^
字符串开头
(?<first>[A-Za-z0-9]*)
命名组 first
,可选择匹配任何列出的范围
<(?<second>[^<>]*)>
匹配 <
然后启动命名组 second
并匹配除 <
和 >
之外的任何字符并匹配 >
(?:
非捕获组
\s+\|\s+(?<first>[A-Za-z0-9]*)<(?<second>[^<>]*)>
在空白字符和两个命名组的相同模式之间匹配 |
)+
关闭群重复1+次
$
字符串结束
看到一个.NET regex demo | C# demo
例如,您可以从匹配中创建元组来创建对。
string str = "i<A> | n<B> | <C>";
MatchCollection matches = Regex.Matches(str, @"^(?<first>[A-Za-z0-9]*)<(?<second>[^<>]*)>(?:\s+\|\s+(?<first>[A-Za-z0-9]*)<(?<second>[^<>]*)>)+$");
foreach (Match match in matches)
{
match.Groups["first"].Captures
.Select(c => c.Value)
.Zip(match.Groups["second"].Captures.Select(c => c.Value), (x, y) => Tuple.Create(x, y))
.ToList()
.ForEach(t => Console.WriteLine("first: {0}, second: {1}", t.Item1, t.Item2));
}
输出
first: i, second: A
first: n, second: B
first: , second: C
我正在尝试制作一个正则表达式来匹配如下字符串:
i<A> | n<B> | <C>
它需要 return 值:
- ("我", "A")
- ("n", "B")
- ("", "C")
目前我正在使用以下正则表达式:
^([A-Za-z0-9]*)\<(.*?)\>
但它只匹配第一对 ("i", "A")。
我找不到修复它的方法。
^ 断言行首的位置,因此如果您删除 i 应该工作,它只会检查每行的开头 并添加一个?对于空值,请参见下面的示例
string pattern = @"([A-Za-z0-9]?)<(.?)>";
string input = @"i<A> | n<B> | <C>";
RegexOptions options = RegexOptions.Multiline;
foreach (Match m in Regex.Matches(input, pattern, options))
{
Console.WriteLine("'{0}' found at index {1}.", m.Value, m.Index);
}
如果 |
是字符串的一部分并且应该被匹配,您可以使用 captures property 和 2 个同名的捕获组。
^(?<first>[A-Za-z0-9]*)<(?<second>[^<>]*)>(?:\s+\|\s+(?<first>[A-Za-z0-9]*)<(?<second>[^<>]*)>)+$
模式匹配:
^
字符串开头(?<first>[A-Za-z0-9]*)
命名组first
,可选择匹配任何列出的范围<(?<second>[^<>]*)>
匹配<
然后启动命名组second
并匹配除<
和>
之外的任何字符并匹配>
(?:
非捕获组\s+\|\s+(?<first>[A-Za-z0-9]*)<(?<second>[^<>]*)>
在空白字符和两个命名组的相同模式之间匹配|
)+
关闭群重复1+次$
字符串结束
看到一个.NET regex demo | C# demo
例如,您可以从匹配中创建元组来创建对。
string str = "i<A> | n<B> | <C>";
MatchCollection matches = Regex.Matches(str, @"^(?<first>[A-Za-z0-9]*)<(?<second>[^<>]*)>(?:\s+\|\s+(?<first>[A-Za-z0-9]*)<(?<second>[^<>]*)>)+$");
foreach (Match match in matches)
{
match.Groups["first"].Captures
.Select(c => c.Value)
.Zip(match.Groups["second"].Captures.Select(c => c.Value), (x, y) => Tuple.Create(x, y))
.ToList()
.ForEach(t => Console.WriteLine("first: {0}, second: {1}", t.Item1, t.Item2));
}
输出
first: i, second: A
first: n, second: B
first: , second: C