var r = new Regex(@"PW\[(?<name>.*)\]");
此正则表达式应与[
和]
之间的名称匹配。但是,如何使正则表达式忽略以\
为前缀的大括号?我缺乏甚至谷歌的术语。
也就是说,我需要它来查找名称等于'inuyasha'的[inuyasha]
,并将[inuyasha\]]
与name = inuyasha\]
匹配。
有意义吗?
校正
最后一场比赛应为inuyasha]
。额外的\
是一个错字。
答案 0 :(得分:2)
你所寻找的术语是“负面的背后隐藏”。请注意,每个正则表达式都不支持此功能。它至少存在于Perl和Java中。
答案 1 :(得分:2)
你不能让正则表达式忽略任何东西 - 而不是你所说的方式。你所描述的是一个三步过程。首先,通过查找封闭的方括号找到名称,同时允许名称中的转义括号:
@"\[(?<name>(?:[^\\\[\]]|\\.)*)\]"
交替的第一部分[^\\\[\]]
是一个否定的字符类,它匹配除反斜杠或方括号之外的任何一个字符。第二部分\\.
匹配反斜杠后跟任何一个字符。第二个角色是什么并不重要;我们需要知道的是,它被反斜杠所逃脱。
第二步是通过捕获组提取名称:
string rawName = m.Groups["name"].Value;
...第三步是删除任何转义的反斜杠:
string name = Regex.Replace(rawName, @"\\(.)", "$1");
把这些全部放在一起,我们有
string test = @"find [inuyasha] or [\[inuyasha] or [inuyasha\]] or [inu\\yasha].";
Regex reg = new Regex(@"\[(?<name>(?:[^][\\]|\\.)*)\]");
foreach (Match m in reg.Matches(test))
{
string rawName = m.Groups["name"].Value;
string name = Regex.Replace(rawName, @"\\(.)", "$1");
Console.WriteLine(name);
}
输出:
inuyasha
[inuyasha
inuyasha]
inu\yasha
注意主正则表达式中缩短的字符类:[^][\\]
。如果类中的第一个字符(或否定^
之后的第一个字符)是右方括号(]
),则将其视为文字字符,而不是字符类的结尾。左方括号([
)始终被视为文字字符,除非它在集合减法表达式中使用(例如[a-z-[aeiou]]
,用于小写辅音)。此信息特定于.NET正则表达式风格;其他口味有自己的规则。
答案 2 :(得分:1)
如果你知道在真正的结束括号之前可能只有一个这样的\]
,你可以使用这样的正则表达式:
PW\[(?<name>.*?(\\\])?)\]
如果可能还有更多,您可以将零或一更改为零或更多:
PW\[(?<name>.*?(\\\])*)\]
对于像“one [two\]] three [four\]\]] five
”这样的字符串,后者会产生这些匹配:
two\]
four\]\]
然后将“替换(”\“”,“]”)移除逃逸将是一件容易的事。
尝试使用lookbehind,但无法让它放弃\
。如果您只匹配]
,就像(?<=\\)\]
这样的模式一样,很棒。只要你想在lookbehind之前捕获字符,lookbehind匹配的字符也将成为结果的一部分。正则表达式不会从捕获组的中间丢弃东西。您要么必须在第二步中处理捕获,要么捕获多个相邻的组并连接您实际需要的组。