使用 Java 匹配正则表达式组
Matching regex groups with Java
我正在尝试通过使用组来使用正则表达式拆分一行,但它没有像我预期的那样工作。
我想匹配例如这一行:
例如。 #1:temp name(this is the data)
还有这个:
例如。 #2:temp name()
我使用了这个正则表达式:
[\s]*temp[\s]+[\s]*([A-Za-z]+)[\s]*[(]\s*(.*)+[)]\s*[{]\s*
这意味着:抓取任何以 temp
开头的内容,然后将 "name" 放入第 1 组,然后抓取括号内的任何内容并将其放入第 2 组。
但是,第 2 组始终为空。
这是我获取数据的代码:
Pattern PATTERN = Pattern.compile("[\s]*temp[\s]+[\s]*([A-Za-z]+)[\s]*[(]\s*(.*)+[)]\s*");
Matcher m = PATTERN.matcher("temp name(this is the data)");
m.matches();
String name = m.group(1);
String data = m.group(2); // always empty
我做错了什么?
您的模式不匹配,因为它需要在末尾有一个左花括号,但您的输入没有。
忽略那个小问题,主要问题是捕获组 (.*)+
之后的小 +
。 plus 需要一个 或更多 个 .*
匹配,返回的组是 最后一个 个匹配。术语 .*
是贪婪的,所以它会消耗括号内的所有内容。再次匹配 的唯一方法是消耗 nothing。所以组 2 的 last 匹配是空白的。
要修复它,请删除第 2 组后的 +
:
Pattern PATTERN = Pattern.compile("\s*temp\s+([A-Za-z]+)\s*[(]\s*(.*)[)]\s*");
另请注意我如何从您的正则表达式中删除其他不必要的字符,例如单字符字符 类 - 即 [\s]
与 \s
相同。 \s+\s*
与 \s+
相同,因为 +
是贪心的。
我还删除了尾随大括号,如果您的输入数据确实有它,您可以恢复它(您的问题显示 "temp name(this is the data)"
的输入,它没有尾随大括号)。
[\s]
等同于 \s
[\s]+[\s]*
等同于 \s+
[(]
等同于 \(
([)]
和 [}]
相同)
这将使您的正则表达式为:
\s*temp\s+([A-Za-z]+)\s*\(\s*(.*)+\)\s*\{\s*
假设您实际上想要匹配 temp name(...) {
(您的正则表达式正在寻找 {
,而在您的问题中您没有指定):
(.*)+
是你的问题。你说的是:"Match any number (including 0) chatacters and put them in a capture group, repeat that at least once"。
正则表达式默认是贪婪的(=它们消耗尽可能多的),所以捕获组将首先包含两个括号内的所有内容,然后 +
将再次尝试匹配整个组,并且将它与 ""
(空字符串)匹配,因为它满足捕获组的模式。这将使您的捕获组变空。
你想要的是 \s*temp\s+([A-Za-z]+)\s*\(\s*(.*)\)\s*\{\s*
你的正则表达式应该是这样的:
Pattern pattern = Pattern.compile("\s*temp\s+([A-Za-z]+)\s*[(]\s*(.*)[)]\s*");
您有 (.*)+
,这意味着 .*
的一个或多个匹配项。这导致什么都没有被捕获。
测试:
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Example {
public static void main(String[] args) {
Pattern pattern = Pattern.compile("\s*temp\s+([A-Za-z]+)\s*[(]\s*(.*)[)]\s*");
Matcher m = pattern.matcher("temp name(this is the data)");
if(m.matches()) {
System.out.println(m.group(1));
System.out.println(m.group(2));
}
}
}
输出:
name
this is the data
你得到空组的原因是每次你在 () 之间放置一些东西时你都会创建多个捕获组,即使它是嵌套的。
要创建一个不捕获的组,您可以使用 ? 将其指定为非捕获组:例如,(?:sometest(this is the value we want))
将 return 仅一组,而 (sometest(this is the value we want))
将return 2组。
对于您的特定正则表达式,我对其进行了改进和简化,因为您拥有不需要的捕获组。
简单的解决方案:
\s*temp\s+([A-Za-z]+)\s*\(\s*(.*)\)\s*\{\s*
给定输入:
Ex. #1: temp name(this is the data) {
Ex. #2: temp name() {
= name, = data
请注意您的正则表达式包含尾随花括号这一事实。您可以修改正则表达式以在没有它的情况下进行匹配,结果将是:
\s*temp\s+([A-Za-z]+)\s*\(\s*(.*)\)\s*
我正在尝试通过使用组来使用正则表达式拆分一行,但它没有像我预期的那样工作。
我想匹配例如这一行:
例如。 #1:temp name(this is the data)
还有这个:
例如。 #2:temp name()
我使用了这个正则表达式:
[\s]*temp[\s]+[\s]*([A-Za-z]+)[\s]*[(]\s*(.*)+[)]\s*[{]\s*
这意味着:抓取任何以 temp
开头的内容,然后将 "name" 放入第 1 组,然后抓取括号内的任何内容并将其放入第 2 组。
但是,第 2 组始终为空。
这是我获取数据的代码:
Pattern PATTERN = Pattern.compile("[\s]*temp[\s]+[\s]*([A-Za-z]+)[\s]*[(]\s*(.*)+[)]\s*");
Matcher m = PATTERN.matcher("temp name(this is the data)");
m.matches();
String name = m.group(1);
String data = m.group(2); // always empty
我做错了什么?
您的模式不匹配,因为它需要在末尾有一个左花括号,但您的输入没有。
忽略那个小问题,主要问题是捕获组 (.*)+
之后的小 +
。 plus 需要一个 或更多 个 .*
匹配,返回的组是 最后一个 个匹配。术语 .*
是贪婪的,所以它会消耗括号内的所有内容。再次匹配 的唯一方法是消耗 nothing。所以组 2 的 last 匹配是空白的。
要修复它,请删除第 2 组后的 +
:
Pattern PATTERN = Pattern.compile("\s*temp\s+([A-Za-z]+)\s*[(]\s*(.*)[)]\s*");
另请注意我如何从您的正则表达式中删除其他不必要的字符,例如单字符字符 类 - 即 [\s]
与 \s
相同。 \s+\s*
与 \s+
相同,因为 +
是贪心的。
我还删除了尾随大括号,如果您的输入数据确实有它,您可以恢复它(您的问题显示 "temp name(this is the data)"
的输入,它没有尾随大括号)。
[\s]
等同于 \s
[\s]+[\s]*
等同于 \s+
[(]
等同于 \(
([)]
和 [}]
相同)
这将使您的正则表达式为:
\s*temp\s+([A-Za-z]+)\s*\(\s*(.*)+\)\s*\{\s*
假设您实际上想要匹配 temp name(...) {
(您的正则表达式正在寻找 {
,而在您的问题中您没有指定):
(.*)+
是你的问题。你说的是:"Match any number (including 0) chatacters and put them in a capture group, repeat that at least once"。
正则表达式默认是贪婪的(=它们消耗尽可能多的),所以捕获组将首先包含两个括号内的所有内容,然后 +
将再次尝试匹配整个组,并且将它与 ""
(空字符串)匹配,因为它满足捕获组的模式。这将使您的捕获组变空。
你想要的是 \s*temp\s+([A-Za-z]+)\s*\(\s*(.*)\)\s*\{\s*
你的正则表达式应该是这样的:
Pattern pattern = Pattern.compile("\s*temp\s+([A-Za-z]+)\s*[(]\s*(.*)[)]\s*");
您有 (.*)+
,这意味着 .*
的一个或多个匹配项。这导致什么都没有被捕获。
测试:
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Example {
public static void main(String[] args) {
Pattern pattern = Pattern.compile("\s*temp\s+([A-Za-z]+)\s*[(]\s*(.*)[)]\s*");
Matcher m = pattern.matcher("temp name(this is the data)");
if(m.matches()) {
System.out.println(m.group(1));
System.out.println(m.group(2));
}
}
}
输出:
name
this is the data
你得到空组的原因是每次你在 () 之间放置一些东西时你都会创建多个捕获组,即使它是嵌套的。
要创建一个不捕获的组,您可以使用 ? 将其指定为非捕获组:例如,(?:sometest(this is the value we want))
将 return 仅一组,而 (sometest(this is the value we want))
将return 2组。
对于您的特定正则表达式,我对其进行了改进和简化,因为您拥有不需要的捕获组。
简单的解决方案:
\s*temp\s+([A-Za-z]+)\s*\(\s*(.*)\)\s*\{\s*
给定输入:
Ex. #1: temp name(this is the data) {
Ex. #2: temp name() {
= name, = data
请注意您的正则表达式包含尾随花括号这一事实。您可以修改正则表达式以在没有它的情况下进行匹配,结果将是:
\s*temp\s+([A-Za-z]+)\s*\(\s*(.*)\)\s*