我想在C#中为我的规则创建一个Regex验证。我有以下规则:
@N货币规模标志
([$]|[~][^~]*[~])?-[1-9][0-9]* (只有尺寸是必需的)下面是Regex:[@][nN]([$]|[~][^~]*[~])?-?[1-9][0-9]*-?([$]|[~][^~]*[~])?
我的问题是,货币和符号应该只发生一次,无论是在size.That的左边还是右边,意味着如果符号已经在左边,那么它就不应该出现在右边了,货币也是如此。
这可以用正则表达式来完成吗?
以下应与之相匹配:
如果与不匹配,则如下所示:
发布于 2017-04-15 12:07:56
您可能不允许使用构造^(?!.*pattern.*pattern)重复模式。对于您的情况,正则表达式如下所示:
(?mx)^
(?!.*([$]|~[^~]*~).*([$]|~[^~]*~))
(?!.*-.*-)
@[nN]([$]|~[^~]*~)?-?[1-9][0-9]*-?([$]|~[^~]*[~])?$Regex演示:https://regex101.com/r/YBhQPB/1
发布于 2017-04-15 12:07:47
我不知道C#是否支持条件表达式,但如果支持条件表达式,则可以使用:
\@[nN](\$)?(-)?[1-9]\d*(?(2)|-)(?(1)|\$)(?:\s|$)解释:
\@[nN] : @ followed by n case insensitive
(\$)? : optional $ sign captured in group 1
(-)? : optional minus sign captured in group 2
[1-9]\d* : value
(?(2)|-) : if group 2 exists then nothing, else minus sign
(?(1)|\$) : if group 1 exists then nothing, else $ sign
(?:\s|$) : a space or end of line下面是一个示例perl脚本:
use Modern::Perl;
my $re = qr~\@[nN](\$)?(-)?[1-9]\d*(?(2)|-)(?(1)|\$)(?:\s|$)~;
while(<DATA>) {
chomp;
say (/$re/ ? "OK: $_" : "KO: $_");
}
__DATA__
@N$7-
@N-7$
@N$-7
@N7-$
@N$5$
@N$-5-
@N-5-
@N7$-
@N-$7输出:
OK: @N$7-
OK: @N-7$
OK: @N$-7
OK: @N7-$
KO: @N$5$
KO: @N$-5-
KO: @N-5-
KO: @N7$-
KO: @N-$7发布于 2017-04-15 13:23:36
如果您对在C#中运行其他测试的regex解决方案表示满意,则可以编写一个简单的方法来验证两个组中只有一个捕获值:
static bool HasOnlyOne(Match m, int g1, int g2) {
if (!m.Success) {
return false;
}
var has1 = m.Groups[g1].Success;
var has2 = m.Groups[g2].Success;
return !has1 || !has2;
}有了这个函数,您可以使用稍微修改过的regex版本来执行测试,如下所示:
var r = new Regex(
@"^[@][nN]([$]|[~][^~]*[~])?(-)?[1-9][0-9]*(-)?([$]|[~][^~]*[~])?$"
// ^ ^ ^ ^
);
string s;
while ((s = Console.ReadLine()) != null) {
var m = r.Match(s);
bool good = HasOnlyOne(m, 1, 4) && HasOnlyOne(m, 2, 3);
if (good) {
Console.WriteLine("Match: {0}", s);
} else {
Console.WriteLine("Fail: {0}", s);
}
}演示。
我在注释中用^标记标记了对regex的修改。
https://stackoverflow.com/questions/43425512
复制相似问题