我想知道c#的正则表达式满足以下模式:
示例:
1-100,134,200 --> PASS. Maximum range of numbers 0-999
1,18,100 --> PASS
1, 18, 100 --> PASS. Allow 0-1 white space after ','
1, 18,100 --> FAIL. Due to more than 1 white space after ','
1-,18,100 --> FAIL. Due to no digit after '-'
-2,18,100 --> FAIL. Due to no digit before '-'
1,,18,100 --> FAIL. Due to no digit between ','
1, ,18,100 --> FAIL. Due to no digit between ','
,2,18,100 --> FAIL. Due to no digit before ','
1,18,100, --> FAIL. Due to no digit after ','
我尝试使用以下代码,但始终返回真实结果:
string pattern = @"[0-9]+(?:-[0-9]+)?(,[0-9]+(?:-[0-9]+)?)*";
string test = @"1-5,13,238,-a";
bool result = Regex.IsMatch(test, pattern);
答案 0 :(得分:7)
您可以使用此正则表达式,
^(?:[1-9]\d\d|[1-9]?\d)(?:-(?:[1-9]\d\d|[1-9]?\d))?(?:,\s?(?:[1-9]\d\d|[1-9]?\d)(?:-(?:[1-9]\d\d|[1-9]?\d))?)*$
说明:
^
-字符串的开头(?:[1-9]\d\d|[1-9]?\d)
-代表0
到999
的数字,并且不允许以005
之类的前导零开头的数字(?:-(?:[1-9]\d\d|[1-9]?\d))?
-(可选)还允许使用连字符-
分隔的数字,因此与第一个正则表达式数字一起,它支持22
和22-33
等数字(?:,\s?(?:[1-9]\d\d|[1-9]?\d)(?:-(?:[1-9]\d\d|[1-9]?\d))?)*
-这部分仅支持逗号分隔,可选地后面跟一个空格,并且整个空格为零或多次。$
-字符串结尾我本可以使用\d{1,3}
来表示从0
到999
的数字,但这将允许像004
这样的数字,似乎不允许您查看样本数据。但是,如果确实允许使用004
或04
之类的数字,则可以在正则表达式中将[1-9]\d\d|[1-9]?\d
替换为\d{1,3}
来简化它。
答案 1 :(得分:6)
您可以尝试
^[0-9]{1,3}(?:\-[0-9]{1,3})?(?:,\s?[0-9]{1,3}(?:\-[0-9]{1,3})?)*$
模式在哪里
^ String start
0*[0-9]{1,3} 1 to 3 digits
(?:\-[0-9]{1,3})? Possible minus (-) followed 1 to 3 digits (e.g. -456)
?:,\s? Comma and at most one whitespace
[0-9]{1,3}(?:\-[0-9]{1,3})?)* 1 to 3 digits or range repeated zero or more times
$ End of string
演示:
string pattern =
@"^[0-9]{1,3}(?:\-[0-9]{1,3})?(?:,\s?[0-9]{1,3}(?:\-[0-9]{1,3})?)*$";
string[] tests = new string[] {
"123",
"1234",
"123-456",
"123,456",
"1-100,134,200",
"1,18,100",
"1, 18, 100",
"1, 18,100",
"1-,18,100",
"-2,18,100",
"1,,18,100",
"1, ,18,100",
",2,18,100",
"1,18,100,",
};
string[] results = tests
.Select(test => $"{test,-20} --> {(Regex.IsMatch(test, pattern) ? "PASS" : "FAIL")}")
.ToArray();
string report = string.Join(Environment.NewLine, results);
Console.Write(report);
结果:
123 --> PASS
1234 --> FAIL
123-456 --> PASS
123,456 --> PASS
1-100,134,200 --> PASS
1,18,100 --> PASS
1, 18, 100 --> PASS
1, 18,100 --> FAIL
1-,18,100 --> FAIL
-2,18,100 --> FAIL
1,,18,100 --> FAIL
1, ,18,100 --> FAIL
,2,18,100 --> FAIL
1,18,100, --> FAIL
修改:
000123
实际上是123
),请将每个[0-9]{1,3}
片段更改为0*[0-9]{1,3}
012
或12
必须失败时必须0
失败),请将每个[0-9]{1,3}
片段更改为(?:0|[1-9][0-9]{0,2})
答案 2 :(得分:3)
尝试以下模式:^(?:\d{1,3}-\d{1,3}|\d{1,3})(?:, ?(?:\d{1,3}-\d{1,3}|\d{1,3}))*$
说明:
^
-匹配字符串的开头
(?:...)
-非捕获组
\d{1,3}
-匹配1到3位数字
-
-从字面上匹配破折号
|
-交替显示,匹配右边的内容(\d{1,3}
或左边的内容(\d{1,3}-\d{1,3}
)
, ?
-匹配,
,后跟零或一个空格
*
-匹配(?:, ?(?:\d{1,3}-\d{1,3}|\d{1,3}))
零次或多次
$
-匹配字符串的结尾
答案 3 :(得分:1)
这是我尝试使用\b
一个单词边界,也许它足够准确以满足您的需求。
^(?:\d{1,3}(?:-\d{1,3})?(?:, ?)?\b)+$
在this demo at regex 101中进行操作(在右侧解释)。
如果您需要不带前导零的0-999 check,请更换\d{1,3}
with (?:[1-9]\d\d?|\d)
答案 4 :(得分:1)
这里似乎有很多异常复杂的答案,所以这是我的2美分:
^([1-9]\d{0,2}|0)((\-|, ?)([1-9]\d{0,2}|0))*$
我认为此答案“不太复杂”,不是因为它简短(这里不是最短),而是因为它不使用“复杂”的正则表达式行为。
它仅使用公用匹配组()
,公用量词(*
,{,}
和?
)和公用匹配符号,例如\d
和[1-9]
没有环顾,前瞻,回溯,非捕获组,反向引用或任何其他“复杂”正则表达式行为
^([1-9]\d{0,2}|0)((\-|, ?)([1-9]\d{0,2}|0))*$
^ Start of string
( Start of capture group:
[1-9]\d{0,2} A non-zero digit followed by 0 to 2 digits.
Matches any 1-999 number without leading zeroes
| OR
0 Just a zero
) End of capture group
( Start of capture group:
( Start of capture group:
\- Dash
| OR
, ? Comma Followed by 1 or 0 spaces
) End of capture group
([1-9]\d{0,2}|0) Same 0-999 capture group as earlier
) End of capture group
* Previous capture group matched 0 or more times
$ End of string
简而言之,以防您需要较少的技术描述:
Number
是0到999之间的数字
(以正则表达式表示:([1-9]\d{0,2}|0)
)
Separator
是逗号加上0或1个空格或破折号
(以正则表达式表示:(\-|, ?)
)
Group
是分隔符,后跟数字
(以正则表达式表示:((\-|, ?)([1-9]\d{0,2}|0))
)
此正则表达式匹配:
数字,后跟零个或多个组
@bobblebubble在评论中指出,这将允许例如1-2-3
,如果-
用于指定范围,则可能不允许。
这是修复此问题的修改:
^(([1-9]\d{0,2}|0)(-([1-9]\d{0,2}|0))?)(, ?(([1-9]\d{0,2}|0)(-([1-9]\d{0,2}|0))?))*$
这比原始的要长得多,因此在C#中,我将其拆分成这样:
// This pattern will match a single 0-999 number, or a range
string numPatt = "(([1-9]\d{0,2}|0)(-([1-9]\d{0,2}|0))?)";
// This pattern will match a csv of numPatts
string pattern = $"^{numPatt}(, ?{numPatt})*$";
然后根据需要使用pattern
。