【问题标题】:How to get substring with pattern using Java如何使用 Java 获取带有模式的子字符串
【发布时间】:2015-04-29 03:55:32
【问题描述】:

我有一个包含以下记录的文件:

drwxr-xr-x   - root supergroup          0 2015-04-05 05:26 /user/root
drwxr-xr-x   - hadoop supergroup          0 2014-11-05 11:56 /user/root/input
drwxr-xr-x   - hadoop supergroup          0 2014-11-05 03:06 /user/root/input/foo
drwxr-xr-x   - hadoop supergroup          0 2015-04-28 03:06 /user/root/input/foo/bar
drwxr-xr-x   - hadoop supergroup          0 2013-11-06 15:54 /user/root/input/foo/bar/20120706
-rw-r--r--   3 hadoop supergroup          0 2013-11-06 15:54 /user/root/input/foo/bar/20120706/_SUCCESS
drwxr-xr-x   - hadoop supergroup          0 2013-11-06 15:54 /user/root/input/foo/bar/20120706/_logs
drwxr-xr-x   - hadoop supergroup          0 2013-11-06 15:54 /user/root/input/foo/bar/20120706/_logs/history

在 Java 代码中,我使用 PatternMatcher 类来获取稍后要处理的子字符串。代码如清单所示:

String filename = "D:\\temp\\files_in_hadoop_temp.txt";
Pattern thePattern
    = Pattern.compile("[a-z\\-]+\\s+(\\-|[0-9]) (root|hadoop)\\s+supergroup\\s+([0-9]+) ([0-9\\-]+) ([0-9:]+) (\\D+)\\/?.*");

    try
    {
        Files.lines(Paths.get(filename))
                .map(line -> thePattern.matcher(line))
                .collect(Collectors.toList())
                .forEach(theMather -> {
                    if (theMather.find())
                    {
                        System.out.println(theMather.group(3) + "-" + theMather.group(4) + "-" + theMather.group(6));
                    }
                });
    } catch (IOException e)
    {
        e.printStackTrace();
    }

结果如下:

0-2015-04-05-/user/root
0-2014-11-05-/user/root/input
0-2014-11-05-/user/root/input/foo
0-2015-04-28-/user/root/input/foo/bar
0-2013-11-06-/user/root/input/foo/bar/
0-2013-11-06-/user/root/input/foo/bar/
0-2013-11-06-/user/root/input/foo/bar/
0-2013-11-06-/user/root/input/foo/bar/

但我的预期结果是前三行没有尾部“/”。我尝试了许多模式来去除拖尾“/”但失败了。

您能否提供一些关于去除尾部“/”的模式的建议。

非常感谢。

【问题讨论】:

  • 正则表达式将仅匹配现有字符串。前 3 个字符串不以“/”结尾。因此,只需使用 if 条件,如果不存在则添加结尾 '/'。

标签: java regex substring


【解决方案1】:

使用字符集确保最后一个字符不是斜线。因此,而不是

(\\D+)\\/?.*"

试试

(\\D*[^\\d/]).*

括号中的部分匹配最长的非数字子串,并增加了最后一个字符不能是斜杠的限制。

注意:已测试。

【讨论】:

  • 这确实是我所期望的,谢谢
【解决方案2】:

你可以做的是检查一个简单的 if 语句,如果最后一个字符是斜线,并使用子字符串获取新字符串:

if (theMather.find())
   {
       String data = theMather.group(3) + "-" + theMather.group(4) + "-" + theMather.group(6);
       //String data = theMather.group(3) + "-" + theMather.group(4) + "-" + theMather.group(6);
       if(data.charAt(data.length() - 1) == '/')
        data = data.substring(0, data.length() - 1);

       System.out.println(data);
   }

【讨论】:

  • @MohanRaj 这通常是错误的问题。这里的很多发帖人都想尝试用正则表达式解决所有问题,但解决问题的最佳方法是行之有效且可读性最强的方式——有时用于解决问题的复杂正则表达式不可读(而且可能不效率,要么)。出于某种原因,程序员爱上了正则表达式,并希望将它们用于所有事情。罗德的回答是可以理解的。这不是“解决方法”。
  • 你也可以使用if (data.endsWith("/"))
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-07-18
  • 2011-02-15
  • 1970-01-01
  • 1970-01-01
  • 2013-01-30
  • 2019-03-29
  • 2011-05-28
相关资源
最近更新 更多