下面由一个例子引出非捕获组。
有两个金额:8899¥。显然,前一个是8899元的人民币,后一个是6688元的美元。我现在需要一个正则,要求提炼出它们的货币金额和货币种类。正则可以这写:(\\d)+([¥$])$ (在Java中测试,所以多了转义字符'\'),最后一个$是字符串结束
测试程序如下:
package test; import java.util.regex.Matcher; import java.util.regex.Pattern; public class main { public static void main(String[] args) { Pattern p = Pattern.compile("(\\d+)([¥$])$");// String str = "8899¥"; Matcher m = p.matcher(str); if (m.matches()) { System.out.println("货币金额: " + m.group(1)); System.out.println("货币种类: " + m.group(2)); } } }
输出结果为:
货币金额: 8899
货币种类: ¥
OK,满足了要求。这里的正则分成了两个组,一个是(\\d+),一个是([¥$]),前一个组匹配货币金额,后一个组匹配货币种类。
现在,我需要这个正则可以匹配浮点数。如8899.56¥。我们都知道,现在少于一元钱基本上买不到东西了,所以我希望忽略小数部分,正则还是提炼出 8899 和 ¥。
那么正则如下:
(\\d+)(\\.?)(\\d+)([¥$])$
这里用括号分了四组,所以要输出货币金额的整数部分和货币种类,要分别输了group(1),group(4)了。如果输出部分和正则是分开的,我希望只修改正则而不去修改输出部分的代码,也就是还是用group(1),group(2)作为输出。由此可以引出非捕获组(?:)。
把前面的正则修改为:
(\\d+)(?:\\.?)(?:\\d+)([¥$])$
这样,还是用group(1),group(2)做为输出,同样输出了 8899 和 ¥
这个正则的中间两个组用到的就是非捕获组(?:),它可以理解为只分组而不捕获。
当然也可以用命名分组,这样直观一点.
package test; import java.util.regex.Matcher; import java.util.regex.Pattern; public class main { public static void main(String[] args) { Pattern p = Pattern.compile("(?<money>\\d+)(?:\\.?)(?:\\d+)(?<type>[¥$])$");// String str = "8899.56¥"; Matcher m = p.matcher(str); if (m.matches()) { System.out.println("货币金额: " + m.group("money")); System.out.println("货币种类: " + m.group("type")); } } }