我不知道如何使用正则表达式来实现这一点(或者如果可以的话;我是正则表达式的新手)。我有一个用户将输入的角度值,我正在尝试验证该条目。它的形式为度 - 分 - 秒。我遇到的问题是,如果用户错误输入秒部分,我必须捕获该错误,但我的度数 - 分钟是成功的。
也许这种方法会更好地解释:
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 =,我的代码中的degreeMinMatchPattern正则表达式将成功匹配,即使它是无效的。
第二次编辑:为了说清楚,分钟和第二部分都是可选的。用户可以键入45,这是有效的。
答案 0 :(得分:4)
您可以使用{m,}
语法指定“模式的此部分必须至少匹配3次”。由于每个组件之间都有连字符,请分别指定第一个部分,然后在每个连字符组合后将其组合在一起:
`[0-9](-[0-9]){2,}`
您还可以将[0-9]
缩短为\d
:\d(-\d){2,}
答案 1 :(得分: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位数字,或任何两位数的数字),但正如示例所示,正则表达式会变得冗长而混乱,所以在代码中记录好你正在做的事情。
答案 2 :(得分:1)
也许你会更好地解析输入并单独检查。
答案 3 :(得分:0)
我不确定我是否理解正确,但我认为
(?<degrees>0*[0-9])-?(?<minutes>0*[0-9])(?:-?(?<seconds>0*[0-9]))?$
可能有用。
但这很模糊;我也想知道为什么你只允许一位数度/分/秒值。请展示一些您不喜欢的例子。
答案 4 :(得分:0)
也许你应该尝试这样的事情并测试空/无效组:
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
);
}
}