我为持续时间写了一个正则表达式
正则表达式是
([0-9]+ (?:[y|Y]ears?|[y|Y]rs?|[m|M]o?nths?|[d|D]a?ys?) ?)+
您可以在 this regex tool 上查看.
匹配的测试用例
- 今年 10 月,我将完成 24 岁。现在我3 个月 短意味着 23 岁 9 个月 19 天。
- ATL 正在为过去10 年 23 个月 19 天的研究工作提供服务。
应该匹配但不匹配的测试用例
- 我二十三岁。
- 22 年 12 个月 30 天前发生了一场灾难。
疑惑
- 帮我检测数字的英文单词,看第3和第4种情况。
已编辑 1
我添加了 reFourDigits
变量来处理 1220
类型的案例。但它没有捕获这一点。请帮助我。以下是有关上述问题的所有详细信息。
public static final String reDigit = "(?:[O|o]ne|[t|T]wo|[t|T]hree|[f|F]our|[f|F]ive|[s|S]ix|[s|S]even|[e|E]ight|[n|N]ine)";
public static final String reTeen = "(?:[t|T]wenty|[t|T]hirty|[f|F]orty|[f|F]ifty|[s|S]ixty|[s|S]eventy|[e|E]ighty|[n|N]inety)";
public static final String re10_19 = "(?:[t|T]en|[e|E]leven|[t|T]welve|[t|T]hirteen|[f|F]ourteen|[f|F]ifteen|[s|S]ixteen|[s|S]eventeen|[e|E]ighteen|[n|N]ineteen)";
public static final String reTwoDigits = "(?:(?:" + reTeen + "[- ])?" + reDigit + "|" + re10_19 + "|" + reTeen + ")";
public static final String reThreeDigits = "(?:(?:" + reDigit + " hundred (?:and)?)?" + reTwoDigits + "|" + reDigit + " hundred)";
public static final String reFourDigits = "(?:" + reTwoDigits + " hundred (?:and)? " + reTwoDigits + ")";
public static final String reSixDigits = "(?:(?:" + reThreeDigits + " thousand (?:and )?)?" + reThreeDigits + "|" + reThreeDigits + " thousand|" + reFourDigits + ")";
public static final String reTwelveDigits = "(?:(?:" + reSixDigits + " million (?:and )?)?" + reSixDigits + "|" + reSixDigits + " million)";
模式是
String patternString = "\\b( ?(?:[,0-9]+|"+Constants.reTwelveDigits+") ?)\\b";
当我运行 There are two22 apples
时。它找到两个字符串 twenty
和 twenty2
,而不是 twenty22
。
最佳答案
就个人而言,我会推荐一个真正的解析器。正则表达式是可能的,但它可能会变成一个非常冗长的模式。下面我用了define来自正则表达式的 PHP 方言,以避免重复模式。如果您选择的正则表达式引擎没有这样的结构,那么您可能需要扩展每个定义,这会导致一个相当长的模式。您仍然可以通过使用简单的字符串连接动态构建模式字符串来避免必须自己写出来。
(?(DEFINE)(?<Digit>one|two|three|four|five|six|seven|eight|nine))
(?(DEFINE)(?<Teen>twenty|thirty|forty|fifty|sixty|seventy|eighty|ninety))
(?(DEFINE)(?<TwoDigits>((?&Teen)-)?(?&Digit)|ten|eleven|twelve|thirteen|fourteen|fifteen|sixteen|seventeen|eighteen|nineteen|(?&Teen)))
(?(DEFINE)(?<ThreeDigits>((?&Digit) hundred (and )?)?(?&TwoDigits)|(?&Digit) hundred))
(?(DEFINE)(?<SixDigits>((?&ThreeDigits) thousand (and )?)?(?&ThreeDigits)|(?&ThreeDigits) thousand))
(?(DEFINE)(?<TwelveDigits>((?&SixDigits) million (and )?)?(?&SixDigits)|(?&SixDigits) million))
fiddle :http://regex101.com/r/oM4oF2
将定义添加到您的表达式中,
然后你可以用 (?:[0-9]+|(?&TwelveDigits))
替换每个 [0-9]+
。
编辑: 据我所知,Java 没有可重用的子模式,因此您必须完全扩展该模式。
string reDigit = "(?:one|two|three|four|five|six|seven|eight|nine)";
string reTeen = "(?:twenty|thirty|forty|fifty|sixty|seventy|eighty|ninety)";
string reTwoDigits = "(?:(?:" + reTeen + "-)?" + reDigit + "|ten|eleven|twelve|thirteen|fourteen|fifteen|sixteen|seventeen|eighteen|nineteen|" + reTeen + ")";
string reThreeDigits = "(?:(?:" + reDigit + " hundred (?:and )?)?" + reTwoDigits + "|" + reDigit + " hundred)";
string reSixDigits = "(?:(?:" + reThreeDigits + " thousand (?:and )?)?" + reThreeDigits + "|" + reThreeDigits + " thousand)";
string reTwelveDigits = "(?:(?:" + reSixDigits + " million (?:and )?)?" + reSixDigits + "|" + reSixDigits + " million)";
string reNumeric = "\\b(?:[0-9]+|" + reTwelveDigits + ")\\b";
我找不到 Java fiddle 站点,所以我改用 JavaScript,它有一个类似的正则表达式引擎:http://jsfiddle.net/f6RmN/
关于java - 用于检测持续时间的正则表达式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24263847/