我有以下测试用例,需要针对这些测试用例开发一个正则表达式,以捕获命名组中的特定信息部分。
测试用例为:
Title v01
Title v01 c01
Title v01 c01-02
Title c01
Title c01-02
要查找的组是:标题,卷,ChapterStart和ChapterEnd。例如,在以下情况下,这些将捕获
Title v02 c05-08
1 2 3 4
1. Title: "Title"
2. Volume: "02"
3. ChapterStart: "05"
4. ChapterEnd: "08"
唯一的必需组是标题,其他组是可选的,如上面列出的其他用例场景所示。
到目前为止,我能够提出以下正则表达式,该正则表达式成功地处理了前三种情况:
(?P<Title>.*)((((( |\.)v))(?P<Volume>\d+))(( |\.)c(?P<ChapterStart>\d+)(-(?P<ChapterEnd>\d+))?)?)
但是,我不知道如何在不必循环使用组名的情况下在一个正则表达式中处理后两种情况。组名称是静态的,因为接收此正则表达式的程序使用它们来提取特定的信息(系列名称,标题,卷号和章号等)。
我现在有两个问题:
如何使正则表达式处理缺少卷信息的情况。
如何将此正则表达式从python重新兼容性转换为Java 1.7 regex兼容性,当前无法完全匹配相同的测试用例。 (我仅通过删除“ P”更改了命名的组符号)
任何帮助将不胜感激。
注意:标题可以是任意数量的单词,包含大写字母,小写字母,数字,特殊字符,unicode字符,以空格,点,下划线和/或破折号等分隔。因此,识别结尾的唯一方法是查找以空格字符(空格,点,下划线等)开头或前后是否到达字符串结尾的av或c。
最佳答案
您的正则表达式中的括号让我感到惊讶,因此我重写了它。这是我想出的:
(?<Title>.*?)( v(?<Volume>\d+))?( c(?<ChapterStart>\d+)(-(?<ChapterEnd>\d+))?)?
注意几件事:
这使用Java 7的命名组
对于标题,我使用的是
reluctant quantifier
,这样它就不会占用整个字符串,而不会为卷和章节留下任何东西。您可以在Pattern api documentation中阅读有关reluctant
,greedy
和possessive
量词的信息。您的卷组后面没有
?
,我相信这会导致Title c01
与章节不匹配。您的v和c前面有一个
( |\.)
部分。我将其删除是因为它与您的测试用例不匹配,并且您似乎没有指示可以使用句点代替空格。如有必要,您可能必须将其放回去。随时适应您的目的。