【问题标题】:Using Regular Expressions to Extract specific Values in Java在 Java 中使用正则表达式提取特定值
【发布时间】:2017-04-19 19:13:12
【问题描述】:

我有几个粗略的字符串:

String s = "Rendering content from websiteNAme using user agent userAgentNameWithSpaces ; for user username ; at time someTime";

我想提取 websiteName、userAgentNameWithSpaces、username 和 someTime 的值。 我已经尝试了以下代码。

private static final Pattern USER_NAME_PATTERN = Pattern.compile("for user.*;");
final Matcher matcher = USER_NAME_PATTERN.matcher(line); 
matcher.find() ? Optional.of(matcher.group(group)) : Optional.empty();

它返回整个字符串“用户用户名”之后我必须用空字符串替换用户字符串以获取用户名。 但是,我想知道是否有正则表达式可以直接获取用户名?

【问题讨论】:

  • 你有没有尝试过?你的String格式也是每次都一样吗?
  • 是的,我尝试了以下代码。 private static final Pattern USER_NAME_PATTERN = Pattern.compile("for user.*;");最终匹配器 matcher = USER_NAME_PATTERN.matcher(line); matcher.find() ? Optional.of(matcher.group(group)) : Optional.empty();它返回整个字符串“for user username”,之后我必须用空字符串替换 for user 字符串以获取用户名。但是,我想知道是否有正则表达式可以直接获取用户名?
  • 用内容编辑您的问题。
  • 我已经更新了问题。

标签: java regex pattern-matching


【解决方案1】:

您可以使用正则表达式组:

Pattern pattern = Pattern.compile("for user (\\w+)");
Matcher matcher = pattern.matcher(s);
if (matcher.find()) {
    System.out.println(matcher.group(1));
}

()这对括号组成一个组,匹配器可以使用group方法获得(因为它是第一个括号,所以它是组1)。

\w 表示“单词字符”(字母、数字和_),+ 表示“一次或多次出现”。所以\w+ 基本上意味着“一个词”(假设您的用户名只有这些字符)。 PS:注意我必须转义\,所以得到的表达式是\\w+

这段代码的输出是:

用户名


如果您想匹配所有值(websiteName、userAgentNameWithSpaces 等),您可以执行以下操作:

Pattern pattern = Pattern.compile("Rendering content from (.*) using user agent (.*) ; for user (.*) ; at time (.*)");
Matcher matcher = pattern.matcher(s);
if (matcher.find()) {
    System.out.println(matcher.group(1));
    System.out.println(matcher.group(2));
    System.out.println(matcher.group(3));
    System.out.println(matcher.group(4));
}

输出将是:

websiteNAme
userAgentNameWithSpaces
username
someTime

请注意,如果userAgentNameWithSpaces 包含空格,\w+ 将不起作用(因为\w 不匹配空格),所以.* 在这种情况下将起作用。


但您也可以使用[\w ]+ - 括号[] 表示“我体内的任何字符”,因此[\w ] 表示“单词字符或空格”(注意@987654340 之间有一个空格@ 和]。所以代码将是(使用带空格的用户名进行测试):

String s = "Rendering content from websiteNAme using user agent userAgent Name WithSpaces ; for user username ; at time someTime";
Pattern pattern = Pattern.compile("Rendering content from (.*) using user agent ([\\w ]+) ; for user (.*) ; at time (.*)");
Matcher matcher = pattern.matcher(s);
if (matcher.find()) {
    System.out.println(matcher.group(1));
    System.out.println(matcher.group(2));
    System.out.println(matcher.group(3));
    System.out.println(matcher.group(4));
}

输出将是:

websiteNAme
userAgent Name WithSpaces
username
someTime

注意:您可以在调用matcher.group(n) 之前测试组是否匹配。 matcher.groupCount() 方法返回匹配的组数(因为如果您调用 matcher.group(n) 并且组 n 不可用,您将获得 IndexOutOfBoundsException

【讨论】:

  • 感谢您的解释。现在,我使用这个表达式来匹配 userAgentWithSpaces。让我知道这是否正确。 Pattern.compile("使用用户代理 ([\\w*\\s*]*)");
  • 这个怎么样。 Pattern TEMPLATE_LOG_PATTERN = Pattern.compile("使用用户代理 (.*) 从 (.*) 渲染内容;对于用户 (.*);在时间 (.*)$");时间 = System.out.println(matcher.group(4).trim());用户名 = System.out.println(matcher.group(3).trim());
【解决方案2】:

我认为您想使用前瞻和后瞻:

String s = "Rendering content from websiteNAme using user agent userAgentNameWithSpaces ; for user username ; at time someTime";
Pattern USER_NAME_PATTERN = Pattern.compile("(?<=for user).*?(?=;)");
final Matcher matcher = USER_NAME_PATTERN.matcher(s);
matcher.find();
System.out.println(matcher.group(0).trim());

输出:

用户名

【讨论】:

  • 工作就像一个魅力。非常感谢。
  • 您可以将.*? 替换为[^;]* 甚至[^;]*+ 以节省一些匹配尝试。
猜你喜欢
  • 1970-01-01
  • 2010-09-19
  • 2014-05-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多