0

我是使用正则表达式的新手,我希望有人可以帮助我。

我有这个正则表达式代码,它应该识别指法文件中的选项卡组。它适用于正则表达式测试网站,例如regexr.comregextester.comextendsclass.com/regex-tester,但是当我使用下面显示的示例文本在 java 中对其进行编码时,我将每一行作为其自己的单独组, 而不是 4 组包含仅由一个换行符分隔的所有文本。我已经阅读了这个堆栈溢出线程“正则表达式适用于 regex101.com,但不适用于 prod”,并且一直小心避免字符串文字问题、多行问题,并且我在 regex101 上尝试了其他正则表达式引擎的代码并且它有效,但是,它在下面显示的我的 java 代码中仍然不起作用。

我尝试启用多行标志,但它仍然不起作用。我认为这是我的代码有问题,但后来我在其他正则表达式测试器网站上得到了相同的错误输出:myregexp.comfreeformatter.com/java-regex-tester

这是原始的正则表达式。它是 ling,所以使用上面的正则表达式可能更容易,因为它们都有我所说的相同问题:

RealRegexCode = (^|[\n\r])(((?<=^|[\n\r])[^\S\n\r]*\|*[^\S\n\r]*((E|A|D|G|B|e|a|d|g|b)[^\S\n\r]*\|*(?=(([^\S\n\r]*-[ -]*(?=\|))|([ -]*((\(?[a-zB-Z0-9]+\)?)+[^\S\n\r]*-[ -]*)+((\(?[a-zB-Z0-9]+\)?)+){0,1}[^\S\n\r]*))[|\r\n]|$)))((([^\S\n\r]*-[ -]*(?=\|))|([ -]*((\(?[a-zB-Z0-9]+\)?)+[^\S\n\r]*-[ -]*)+((\(?[a-zB-Z0-9]+\)?)+){0,1}[^\S\n\r]*))\|)+(((?<=\|)[^\S\n\r]*((E|A|D|G|B|e|a|d|g|b)[^\S\n\r]*\|*(?=(([^\S\n\r]*-[ -]*(?=\|))|([ -]*((\(?[a-zB-Z0-9]+\)?)+[^\S\n\r]*-[ -]*)+((\(?[a-zB-Z0-9]+\)?)+){0,1}[^\S\n\r]*))[|\r\n]|$)))((([^\S\n\r]*-[ -]*(?=\|))|([ -]*((\(?[a-zB-Z0-9]+\)?)+[^\S\n\r]*-[ -]*)+((\(?[a-zB-Z0-9]+\)?)+){0,1}[^\S\n\r]*))\|)+)*(\n|\r|$))+

这是显示相同问题的简化正则表达式代码,提供用于调试

SimplifiedRegexCode = (^|[\n\r])([^\n\r]+(\n|\r|$))+

这是使用正则表达式模式查找匹配项的代码:

public static void main(String[] args){
        String filePath = "C:\\Users\\stani\\IdeaProjects\project\\src\\testing files\\guitar - a thousand matches by passenger.txt";
        Path path = Path.of(filePath);
        List<String> stuff = new ArrayList<>();
        try {
            String rootStr = Files.readString(path);
            Pattern pattern = Pattern.compile("(^|[\\n\\r])([^\\n\\r]+(\\n|\\r|$))+");
            Matcher ptrnMatcher = pattern.matcher(rootStr);
            while (ptrnMatcher.find()) {
                stuff.add(ptrnMatcher.group());
            }
        }catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println(new Patterns().MeasureGroupCollection);
        for (String s:stuff)
            System.out.println(s);
    }

这是我正在测试它的文本。将其复制并粘贴到文本编辑器中可能会有所帮助,因为堆栈溢出可能会扭曲文本的外观:

e|---------------------------------|------------------------------------|
e|------------------------------------------------------------------|
B|-----1--------(1)----1-----------|-------1---------------1----------1-|
B|-----1--------(1)----0---------0-----1---------1-----3--------(3)-|
G|-----------0------------0--------|-------------0----------------0-----|
G|-----------0---------------0---------------0---------------0------|
D|-----0h2-----2-------2-----------|-------2-------2-------0--------0---|
D|-----2-------2-------2-------2-------2-------2-------0-------0----|
A|-3-------3-------3-------3-------|------------------------------------|
A|-0-------0--------------------------------------------------------|
E|-----------------------------0---|---1-------1-------3-------3--------|
E|-----------------0-------0--------1------1-------3-------3--------|


e|-------------------------------------------------------------------|
B|-----1---------1-----1---------1-----3---------3-------1---------1-|
G|-----------0---------------0---------------0-----------------0-----|
D|-----3-------2-------2-------2-------0-------0---------2-------2---|
A|-----------------3-------3-------------------------3-------3-------|
E|-1-------1-----------------------3-------3-------------------------|

它应该从文本中识别出四个不同的组。但是,在 java 和我上面提到的两个测试器中,它会将每一行识别为自己的不同组(即 12 个组)

4

1 回答 1

0

因为我熟悉正则表达式和吉他哈哈,所以我忍不住对此做出了回应。

对于您的简短正则表达式,请在 regex101.com 上查看以下正则表达式: https ://regex101.com/r/NqGhoh/1/

多行修饰符是必需的。

这样做的主要问题是您正在处理表达式前后的换行符。我以几种方式修改了表达式:

  • ^使正则表达式仅在末尾匹配换行符,始终在开头寻找 a 。
  • 将回车换行组合匹配为 \r?\n 作为回车,在使用时应始终后跟换行。
  • 使用非捕获组来改善开销并降低查看匹配项时的复杂性。这是?:括号内的内容。这意味着该组不会被捕获在结果中,仅用于封装。

我开始测试您较长的正则表达式并且可能会对其进行更新,尽管听起来您已经知道如何处理较短的正则表达式已更正。

于 2021-02-01T23:41:01.007 回答