C# [0-9]-[0-9]-[0-9]的匹配模式,但不匹配[0-9]-[0-9]
我不知道如何用正则表达式来实现这一点(或者如果可以,我对正则表达式还不熟悉)。我有一个用户将输入的角度值,我正在尝试验证输入。它的形式是度分秒。我遇到的问题是,如果用户错误地键入秒数部分,我必须捕获该错误,但我的匹配度分钟是成功的 也许这种方法能更好地解释:C# [0-9]-[0-9]-[0-9]的匹配模式,但不匹配[0-9]-[0-9],c#,regex,C#,Regex,我不知道如何用正则表达式来实现这一点(或者如果可以,我对正则表达式还不熟悉)。我有一个用户将输入的角度值,我正在尝试验证输入。它的形式是度分秒。我遇到的问题是,如果用户错误地键入秒数部分,我必须捕获该错误,但我的匹配度分钟是成功的 也许这种方法能更好地解释: private Boolean isTextValid(String _angleValue) { Regex _degreeMatchPattern = new Regex("0*[1-9]");
private Boolean isTextValid(String _angleValue) {
Regex _degreeMatchPattern = new Regex("0*[1-9]");
Regex degreeMinMatchPattern = new Regex("(0*[0-9]-{1}0*[0-9]){1}");
Regex degreeMinSecMatchPattern = new Regex("0*[0-9]-{1}0*[0-9]-{1}0*[0-9]");
Match _degreeMatch, _degreeMinMatch, _degreeMinSecMatch;
_degreeMinSecMatch = degreeMinSecMatchPattern.Match(_angleValue);
if (_degreeMinSecMatch.Success)
return true;
_degreeMinMatch = degreeMinMatchPattern.Match(_angleValue);
if (_degreeMinMatch.Success)
return true;
_degreeMatch = _degreeMatchPattern.Match(_angleValue);
if (_degreeMatch.Success)
return true;
return false;
}
}
如果度-分-秒匹配不成功,我想检查度-分,但前提是用户没有输入任何秒数据。我可以通过正则表达式来实现这一点,还是需要解析字符串并分别计算每个部分?谢谢
编辑:样本数据将为45-23-10作为正确数据。问题是45-23也是有效数据;0秒是可以理解的。因此,如果用户在意外情况下键入45-23-1=,则代码中的degreeMatchPattern regex将成功匹配,即使它无效
第二次编辑:为了清楚起见,分钟和第二部分都是可选的。用户可以键入45,这是有效的。也许您最好只解析输入并单独检查is片段。我不确定我是否理解正确,但我认为
(?<degrees>0*[0-9])-?(?<minutes>0*[0-9])(?:-?(?<seconds>0*[0-9]))?$
(?0*[0-9])-?(?0*[0-9])(?:-?(?0*[0-9]))$
可能有用
但这是相当含糊的;另外,我想知道为什么只允许一位数的度/分/秒值。请给出一些您想匹配和不想匹配的示例。您可以使用{m,}
语法指定“模式的此部分必须至少匹配3次”。由于每个组件之间都有连字符,请分别指定第一部分,然后可以在以下情况下将每个连字符数字组合组合组合在一起:
`[0-9](-[0-9]){2,}`
您还可以将
[0-9]
缩短为\d
:\d(-\d){2,}
首先,正则表达式中的字符默认匹配一次,因此{1}是多余的
其次,由于您显然可以隔离此值(您只提示输入此值,而不必在输入数据的段落中查找),因此您应该在字符串中包含“^”和“$”,以强制该字符串只包含此模式
请尝试“^\d{1,3}-\d{1,2}(-\d{1,2})?$”
分解:^匹配字符串的开头\d匹配任何一个十进制字符,然后在后面指定{1,3},它将匹配任何数字的一到三个匹配项。然后你要寻找一个破折号,然后是一个类似的十进制模式,但只有一两次。最后一项用括号括起来,这样我们就可以把字符分组了。它的形式类似于前两个,那么有一个?它将前面的字符组标记为可选。末尾的$表示输入应该结束。因此,它将匹配222-33-44或222-33,但不匹配222-3344或222-33-abc
请记住,您可能需要合并其他规则。例如,秒可以表示为十进制(如果您希望分辨率小于1秒)。您可能需要选择小数点和一个或多个附加数字。此外,您可能有一个最大度数值;上述正则表达式将匹配最大整数DMS值359-59-59,但它也将匹配无效的999-99-99。您可以使用正则表达式来限制最大值(例如“(3[0-5]\d|[1-2]\d{2}|\d{1,2})”将匹配0到359之间的任何数字,方法是匹配一个3,然后是0-5,然后是0-9,或任何以1或2开头的3位数字,或任何两位数字),但如示例所示,正则表达式将变得冗长而混乱,因此,请用代码很好地记录您正在做的事情。也许您应该尝试类似的方法,并测试空组/无效组:
Regex degrees = new Regex(
@"(?<degrees>\d+)(?:-(?<minutes>\d+))?(?:-(?<seconds>\d+))?");
string[] samples = new []{ "123", "123-456", "123-456-789" };
foreach (var sample in samples)
{
Match m = degrees.Match(sample);
if(m.Success)
{
string degrees = m.Groups["degrees"].Value;
string minutes = m.Groups["minutes"].Value;
string seconds = m.Groups["seconds"].Value;
Console.WriteLine("{0}°{1}'{2}\"", degrees,
String.IsNullOrEmpty(minutes) ? "0" : minutes,
String.IsNullOrEmpty(seconds) ? "0" : seconds
);
}
}
Regex度=新的Regex(
@“(?\d+)(:-(?\d+))(?:-(?\d+))”;
字符串[]samples=new[]{“123”、“123-456”、“123-456-789”};
foreach(样本中的var样本)
{
匹配m=度。匹配(样本);
如果(m.成功)
{
字符串度数=m.组[“度数”].值;
字符串minutes=m.Groups[“minutes”].Value;
字符串秒=m.Groups[“seconds”].值;
Console.WriteLine(“{0}°{1}'{2}\”,度,
String.IsNullOrEmpty(分钟)?“0”:分钟,
String.IsNullOrEmpty(秒)?“0”:秒
);
}
}
你有一些样本数据吗?它是45-23-1=。我想你只是没有看到等号。也许更好的例子是45-23-1A。很抱歉混淆了。我想他想匹配2或3个数字,但只有在没有后面的情况下才匹配2个数字,而不是在后面有无效输入的情况下匹配2个数字。只需稍作修改(因为三者中的第二个也是可选的,C#需要第二个反斜杠来正确地转义d)这是有效的。我的最终表达式是“^\\d{1,3}(-\\d{1,2}(-\\d{1,2}”)?$”。谢谢!如果在打开字符串的双引号前面放一个@,NET将自动转义任何需要它的字符。这对文件很有用(反斜杠目录分隔符)和多行数据(\r\n无处不在)以及正则表达式。今天我还学到了一些其他内容(我知道多行数据,但不知道正则表达式)。谢谢!