Java 正则表达式将一个符号分组并忽略该符号的其他引用

Java 正则表达式将一个符号分组并忽略该符号的其他引用,java,regex,string,Java,Regex,String,对于我正在处理的项目,我必须解析表单中的字符串列表 Comparing folder1name-folder2name: x 其中x是一个十进制值。我想使用regex模式和matcher将每一行分组到它各自的元素中,这样我就可以很容易地提取文件夹名称和值(稍后将使用) 我构建了以下模式,效果很好 String pattern = "(Comparing )(.*)(-)(.*)(: )(\\d+\\.\\d+)"; Pattern p = Pattern.com

对于我正在处理的项目,我必须解析表单中的字符串列表

Comparing folder1name-folder2name: x
其中x是一个十进制值。我想使用regex模式和matcher将每一行分组到它各自的元素中,这样我就可以很容易地提取文件夹名称和值(稍后将使用)

我构建了以下模式,效果很好

        String pattern = "(Comparing )(.*)(-)(.*)(: )(\\d+\\.\\d+)";
        Pattern p = Pattern.compile(pattern);
        Matcher m = p.matcher(data);
        while (m.find()){
            String f1 = m.group(2);
            String f2 = m.group(4);
            String value = m.group(6);
        }
当-出现在文件夹名称中时会出现问题,因为模式无法分辨文件夹名称的结束位置和分隔位置。 e、 g

  • 可以安全地假设,如果文件夹名称中出现破折号,则两个名称中的破折号数量始终相等。有没有办法让一个模式来解释这种可能性,而不是将名称中的a-误认为分隔符
  • 关于存储/读取非常大的字符串的额外问题

  • 我使用的字符串数据来自命令行操作,可能非常长,可能超过数十万个字符(取决于文件夹的数量)。目前,我正在从进程中获取输入流,将其转换为字符串生成器,然后在构建时将其存储为我可以读取的字符串

    有没有更有效的方法?我应该作为StringBuilder阅读和解析它吗?我希望能够快速读取数据,但担心在一个字符串对象中存储这么多数据。我不希望绳子有可能太大


  • 谢谢

    有时候少就是多。我甚至不想把所有的逻辑都推到正则表达式中。相反,我只为文件夹获取一个字符串:

    String pattern = "(Comparing )(.*)(: )(\\d+\\.\\d+)";
    
    然后使用一些单独的逻辑来拆分文件夹(使用
    -
    破折号)。这将为您提供更多的控制(例如,当破折号为奇数时,您可以抛出异常),并使程序更易于理解

    关于第二个问题:
    如果这只是一个工具,您可以自己使用,只需使用单个字符串,直到它失败


    另外,您可以只考虑逐行处理输入行:例如得到一行,应用正则表达式,拆分文件夹,并将其写入另一个文件或某处。

    < P>首先在字符串中计数HyPing事件(在我使用的代码< StrutuLSL</代码>的例子中,但有很多方法),然后使用此数字的一半来平衡两个文件夹的名称:

    int count = StringUtils.countMatches(data, "-");
    count /= 2;
    String pattern = String.format("(Comparing )((?:.*-){%d}.*)(-)((?:.*-){%d}.*)(: )(\\d+\\.\\d+)", count, count);
    

    然后做你必须做的事。

    我看不出有任何方法可以区分文件夹名称中的连字符和分隔文件夹名称的连字符。我同意@TimBiegeleisen的观点。。即使使用一些正则表达式技巧来获得您想要的结果,如果文件名稍有更改(或者如果连字符不平衡),这种方法也会失败。每个文件名中的破折号数量是否有合理限制?请发布一些测试用例,如果它们都能正确匹配,您将得到答案(我知道如何解决这个问题,但我想确保我理解这个问题)那么任何单个文件名中的最大连字符数是1吗?如果不是,最大数是多少?如果按照您的假设,两个文件名中的破折号数始终相等,则此方法有效。
    int count = StringUtils.countMatches(data, "-");
    count /= 2;
    String pattern = String.format("(Comparing )((?:.*-){%d}.*)(-)((?:.*-){%d}.*)(: )(\\d+\\.\\d+)", count, count);