我有一个非常长的字符串,我要解析在子字符串“ISBN”之后出现的数值。但是,这种13位数的分组可以通过“ - ”字符进行不同的排列。示例:(这些都是有效的ISBN)123-456-789-123-4
,或1-2-3-4-5-67891234
,或12-34-56-78-91-23-4
。基本上,我想在潜在的ISBN上使用正则表达式模式匹配器来查看是否存在有效的13位ISBN。我如何“忽略”“ - ”字符,以便我可以正则表达式为\d{13}
模式?我的功能:
public String parseISBN (String sourceCode) {
int location = sourceCode.indexOf("ISBN") + 5;
String ISBN = sourceCode.substring(location); //substring after "ISBN" occurs
int i = 0;
while ( ISBN.charAt(i) != ' ' )
i++;
ISBN = ISBN.substring(0, i); //should contain potential ISBN value
Pattern pattern = Pattern.compile("\\d{13}"); //this clearly will find 13 consecutive numbers, but I need it to ignore the "-" character
Matcher matcher = pattern.matcher(ISBN);
if (matcher.find()) return ISBN;
else return null;
}
答案 0 :(得分:8)
备选方案1:
pattern.matcher(ISBN.replace("-", ""))
备选方案2:像
这样的东西Pattern.compile("(\\d-?){13}")
第二种选择的演示:
String ISBN = "ISBN: 123-456-789-112-3, ISBN: 1234567891123";
Pattern pattern = Pattern.compile("(\\d-?){13}");
Matcher matcher = pattern.matcher(ISBN);
while (matcher.find())
System.out.println(matcher.group());
<强>输出:强>
123-456-789-112-3
1234567891123
答案 1 :(得分:5)
试试这个:
Pattern.compile("\\d(-?\\d){12}")
答案 2 :(得分:3)
使用此模式:
Pattern.compile("(?:\\d-?){13}")
并从找到的isbn数字中删除所有破折号
答案 3 :(得分:2)
使用识别所有内容的模式和数字之间的可选短划线一步完成。无需摆弄ISBN偏移+子串。
ISBN(\d(-?\d){12})
如果您想要原始数字,请在之后从第一个匹配的子组中删除破折号。 我不是一个Java人,所以我不会告诉你代码。
答案 4 :(得分:2)
如果您要调用该方法,那么您可以做的最好的事情是不在其中编译Pattern。否则,每次调用该方法时,您将花费更多时间创建正则表达式而不是实际搜索它。
但是在再次查看你的代码后,我认为你有一个更大的问题,性能方面。所有那些定位“ISBN”然后创建子串以应用正则表达式的业务是完全没有必要的。让正则表达式做那些东西;这就是他们的目的。以下正则表达式发现“ISBN”sentinel 和以下十三位数字,如果它们在那里:
static final Pattern isbnPattern = Pattern.compile(
"\\bISBN[^A-Z0-9]*+(\\d(?:-*+\\d){12})", Pattern.CASE_INSENSITIVE );
[^A-Z0-9]*+
吞噬了“ISBN”和第一个数字之间可能出现的任何字符。占有量词(*+
)可以防止不必要的回溯;如果下一个字符不是数字,则正则表达式引擎会立即退出该匹配尝试并继续扫描另一个“ISBN”实例。
我为可选连字符使用了另一个所有格量词,并为重复部分使用了非捕获组((?:...)
);与大多数其他响应者正在使用的捕获组相比,它可以获得另一个轻微的性能提升。但是我使用了捕获组来获取整个数字,因此可以轻松地从整体匹配中提取它。通过这些更改,您的方法可以简化为:
public String parseISBN (String source) {
Matcher m = isbnPattern.matcher(source);
return m.find() ? m.group(1) : null;
}
......而且效率也高得多。请注意,我们还没有解决字符串进入内存的方式。如果您自己在进行I / O操作,那么在该领域也可能会有显着的性能提升。
答案 5 :(得分:1)
您可以使用字符串操作删除破折号,或者您可以使用:
"\\b(?:\\d-?){13}\\b"
它确保字符串不会以-
开头或结尾。
答案 6 :(得分:0)
尝试剥离破折号,并使用正则表达式新字符串