首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >只有当实例发生一次时,才匹配Regex。

只有当实例发生一次时,才匹配Regex。
EN

Stack Overflow用户
提问于 2017-04-15 11:31:39
回答 3查看 2K关注 0票数 2

我想在C#中为我的规则创建一个Regex验证。我有以下规则:

@N货币规模标志

  • 货币:([$]|[~][^~]*[~])?
  • 标志:-
  • 尺寸:[1-9][0-9]* (只有尺寸是必需的)

下面是Regex:[@][nN]([$]|[~][^~]*[~])?-?[1-9][0-9]*-?([$]|[~][^~]*[~])?

我的问题是,货币和符号应该只发生一次,无论是在size.That的左边还是右边,意味着如果符号已经在左边,那么它就不应该出现在右边了,货币也是如此。

这可以用正则表达式来完成吗?

以下应与之相匹配:

  • @$7-
  • @N-7$
  • @N$-7
  • @N7-$

如果不匹配,则如下所示:

  • @$5
  • @N$-5-
  • @N-5-
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2017-04-15 12:07:56

您可能不允许使用构造^(?!.*pattern.*pattern)重复模式。对于您的情况,正则表达式如下所示:

代码语言:javascript
复制
(?mx)^
(?!.*([$]|~[^~]*~).*([$]|~[^~]*~))
(?!.*-.*-)
@[nN]([$]|~[^~]*~)?-?[1-9][0-9]*-?([$]|~[^~]*[~])?$

Regex演示:https://regex101.com/r/YBhQPB/1

C#演示:https://dotnetfiddle.net/8jG3y4

票数 2
EN

Stack Overflow用户

发布于 2017-04-15 12:07:47

我不知道C#是否支持条件表达式,但如果支持条件表达式,则可以使用:

代码语言:javascript
复制
\@[nN](\$)?(-)?[1-9]\d*(?(2)|-)(?(1)|\$)(?:\s|$)

解释:

代码语言:javascript
复制
\@[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脚本:

代码语言:javascript
复制
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

输出:

代码语言:javascript
复制
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
票数 2
EN

Stack Overflow用户

发布于 2017-04-15 13:23:36

如果您对在C#中运行其他测试的regex解决方案表示满意,则可以编写一个简单的方法来验证两个组中只有一个捕获值:

代码语言:javascript
复制
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版本来执行测试,如下所示:

代码语言:javascript
复制
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的修改。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/43425512

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档