繁体   English   中英

Java 正则表达式重复捕获组

[英]Java regex repeating capture groups

考虑以下字符串:“${test.one}${test.two}”我希望我的正则表达式返回两个匹配项,即“test.one”和“test.two”。 为此,我有以下代码段:

导入 java.util.regex.Matcher; 导入 java.util.regex.Pattern;

public class RegexTester {

    private static final Pattern pattern = Pattern.compile("\\$\\{((?:(?:[A-z]+(?:\\.[A-z0-9()\\[\\]\"]+)*)+|(?:\"[\\w/?.&=_\\-]*\")+)+)}+$");

    public static void main(String[] args) {
        String testString = "${test.one}${test.two}";

        Matcher matcher = pattern.matcher(testString);

        while (matcher.find()) {
            for (int i = 0; i <= matcher.groupCount(); i++) {
                System.out.println(matcher.group(i));
            }
        }
    }
}

我还有一些其他的东西,因为我希望这也是一个有效的匹配 ${test.one}${"hello"}。

所以,基本上,我只希望它匹配 ${} 内的任何内容,只要它遵循以下格式: something.somethingelse (仅存在字母数字)或something.somethingElse()"something inside of quotations" (字母数字加其他一些字符)。 我有主要的正则表达式工作,或者我认为,但是当我运行代码时,它会找到两个组,

${test.two} test.two

我希望 output 成为

测试一测试二

基本上,您的正则表达式的主要问题是它仅在字符串的末尾匹配,并且您匹配更多的字符,而只是带有[Az]的字母。 您的分组似乎也关闭了。

如果你在 regex101 加载你的正则表达式,你会看到它匹配

  • \$\{
  • ( - 捕获组的开始
    • (?: - 非捕获组的开始
      • (?:[Az]+ - 非捕获组的开始,它匹配Az之间的 1+ 个字符(您的第一个错误
        • (?:\.[A-z0-9()\[\]\"]+)* - 0 次或多次重复 a .然后 1+ 字母、数字、 ( , ) , [ , ] , " , \ , ^ , _和一个反引号
      • )+ - 重复非捕获组 1 次或多次
      • | - 或者
      • (?:\"[\w/?.&=_\-]*\")+ - 1 次或多次出现" ,0 或多个单词, /?.&=_-字符和然后一个"
      • )+ - 重复组模式 1+ 次
    • ) - 非捕获组结束
  • }+ - 1+ }个字符
  • $ - 字符串结束。

要匹配字符串中出现的任何模式,您需要使用

\$\{(\"[^\"]*\"|\w+(?:\(\))?(?:\.\w+(?:\(\))?)*)}

查看正则表达式演示,找到匹配项后获取第 1 组值。 细节:

  • \$\{ - ${ substring
  • (\"[^\"]*\"|\w+(?:\(\))?(?:\.\w+(?:\(\))?)*) - 捕获组1:
    • \"[^\"]*\" - " ,除"之外的 0+ 个字符,然后是"
    • | - 或者
    • \w+(?:\(\))? - 1+ 字字符和一个可选的() substring
    • (?:\.\w+(?:\(\))?)* - 0 次或多次重复. 然后是 1+ 字字符和一个可选的() substring
  • } - 一个}字符。

请参阅Java 演示

String s = "${test.one}${test.two}\n${test.one}${test.two()}\n${test.one}${\"hello\"}";
Pattern pattern = Pattern.compile("\\$\\{(\"[^\"]*\"|\\w+(?:\\(\\))?(?:\\.\\w+(?:\\(\\))?)*)}");
Matcher matcher = pattern.matcher(s);
while (matcher.find()){
    System.out.println(matcher.group(1)); 
} 

Output:

test.one
test.two
test.one
test.two()
test.one
"hello"

你可以使用正则表达式

(?<=\$\{")[a-z]+(?="\})|(?<=\$\{)[a-z]+\.[a-z]+(?:\(\))?(?=\})

没有捕获组。 字符类[az]可以根据需要进行修改,前提是它们不包含双引号、句点或右大括号。

演示

Java 的正则表达式引擎执行以下操作。

(?<=\$\{")  # match '${"' in a positive lookbehind
[a-z]+      # match 1+ lowercase letters 
(?="\})     # match '"}' in a positive lookahead
|           # or 
(?<=\$\{)   # match '${' in a positive lookbehind
[a-z]+      # match 1+ lowercase letters 
\.[a-z]+    # match '.' followed by 1+ lowercase letters
(?:\(\))?   # optionally match `()`
(?=\})      # match '}' in a positive lookahead

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM