我需要从这样的字符串中获取数字:
我的第一直觉是这样做:
\w+\.((\[(?<number>\d+)\])|(?<number>\d+))\.\w+
但这会失败并出现错误:“?子模式名称必须是唯一的”。
你的正则表达式很好,但是,你不能有 2 个括号组并将它们都命名为“number”。我知道您想获取“匹配的任何一个”,但这不是正则表达式的工作方式 - 您必须获取组 1,如果是
null
,则获取组 2。将它们命名为您想要的名称,或者不命名它们:
Pattern p = Pattern.compile("\\w+\\.((\\[(\\d+)\\])|(\\d+))\\.\\w+");
Matcher m = p.matcher("prefix.[10].suffix");
if (m.matches()) {
String raw = m.group(1);
if (raw == null) raw = m.group(2);
return Integer.parseInt(raw);
}
如果您只对数字感兴趣,那么您不需要单词字符
+
的量词 \w+
,因为 1 也足够了。
Java 支持环视断言,这将允许您对两种场景使用交替,并且仅在不使用组的情况下获得匹配。
(?<=\w\.)\d+(?=\.\w)|(?<=\w\.\[)\d+(?=]\.\w)
模式匹配:
(?<=\w\.)\d+(?=\.\w)
在左侧断言一个单词字符,后跟一个点,匹配 1+ 个数字,然后在右侧断言一个点和一个单词字符|
或者(?<=\w\.\[)\d+(?=]\.\w)
与第一部分相同,但现在断言中包含 [
和 ]
在 Java 中使用双重转义符:
String regex = "(?<=\\w\\.)\\d+(?=\\.\\w)|(?<=\\w\\.\\[)\\d+(?=]\\.\\w)";
(\.\[*(.*)\]*\.)
这将与 .[10] 匹配。或 .10.
比赛将分为两个小组。第 1 组将是.[10]。第 2 组将为 10 您可以在第 2 组中获得所需的值。
\.
- 期待一个点
\[*
- 期望 0 或更多 [
(.*)
- 与任何角色匹配
\]*
- 预计 0 或更多 ]
\.
- 期待一个点
基本上 (.*) 该组将捕获 .[ 和 ] 之间的任何内容。其中 [ 和 ] 是可选的。您可以根据您的要求将此处的 [ 和 ] 替换为任何字符集。
例如是否可以用除数字之外的任何字符来代替 [ 和 ]
(\.[^0-9]*([0-9]+)[^0-9]*\.)