【问题标题】:What is wrong with the pattern matching?模式匹配有什么问题?
【发布时间】:2014-03-05 04:57:33
【问题描述】:

这个程序应该匹配

(as(fd))_n

并将其转换为

\pochhammer{as(fd)}{n}

但是,它没有正确转换字符串。它正在转换

W_n(-a^2;a,b,c,d)=(a+b)_n(a+c)_n(a+d)_n\,,

W_n\pochhammer{-a^2;a,b,c,d)=(a+b}{n}\pochhammer{a+c}{n}\pochhammer{a+d}{n}\ ,,

什么时候应该转换成

W_n(-a^2;a,b,c,d)=\pochhammer{a+b}{n}\pochhammer{a+c}{n}\pochhammer{a+d}{n}\ ,,

这是我的代码:

while(scanner.hasNextLine()) {
    String line = scanner.nextLine();
    Pattern cpochhammer = Pattern.compile("(\\((.*?)\\)_\\{([^}]+)\\})");
    Matcher pochhammer = cpochhammer.matcher(line);
    StringBuffer rplcmntBfr = new StringBuffer();

    while(pochhammer.find())  {
        pochhammer.appendReplacement(rplcmntBfr, "\\\\pochhammer{$2}{$3}");
    }

    pochhammer.appendTail(rplcmntBfr);  
    Pattern npochhammer = Pattern.compile("(\\((.*?)\\)_(.))");
    Matcher ppochhammer = npochhammer.matcher(rplcmntBfr. toString() );
    rplcmntBfr.setLength(0);

    while(ppochhammer.find())  {
        ppochhammer.appendReplacement(rplcmntBfr, "\\\\pochhammer{$2}{$3}");
    }

    ppochhammer.appendTail(rplcmntBfr);
    writer.println(rplcmntBfr);
}

谢谢。

【问题讨论】:

  • match (as(fd))_n - 你能详细说明一下吗?显然,以您的示例为例,您的意思不是那个文字字符串;你想匹配什么?
  • 如果你有嵌套的括号,java 的正则表达式现在无法处理这些。
  • Jerry 是对的,找到平衡括号的唯一方法是使用支持递归的第三方正则表达式库或编写自己的解析器。
  • @OP 检查我的更新答案,尤其是关于 .*?[^)]* 的部分。

标签: java regex pattern-matching


【解决方案1】:

我可能弄错了,但也许你正在寻找类似的东西

String replaced = line.replaceAll("\\(([^)]*)\\)_(\\w+)", "\\\\pochhammer{$1}{$2}");
//                                                ^^^^ 
//                                  You can use \\d or \\d+ instead
//                                  this part. I am not sure what `n` can be

当您更详细地描述您的问题时,我可以尝试更正我的答案,例如您尝试通过第一个循环实现什么?在这里用\\\\pochhammer{$2}{$3} 替换"(\\((.*?)\\)_\\{([^}]+)\\})" 似乎毫无意义,因为您的输入中没有(xxx)_{n}

所以唯一的问题似乎是你的第二个正则表达式(\\((.*?)\\)_(.))。如果您仔细查看它,则不需要外括号,因为它们只会使第 1 组第 2 组,所以而不是

    (\\((.*?)\\)_(.)) you can use 
     \\((.*?)\\)_(.)

接下来是你使用.*?,这意味着可以匹配任何字符,所以\\((.*?)\\)_将匹配任何字符,首先是(,最后是),它后面有_,就像你的情况一样

 W_n(-a^2;a,b,c,d)=(a+b)_n(a+c)_n(a+d)_n\,,
     ^^^^^^^^^^^^^^^^^^
     this part

结果给你

 W_n\pochhammer{-a^2;a,b,c,d)=(a+b}{n}\pochhammer{a+c}{n}\pochhammer{a+d}{n}\,,
                ^^^^^^^^^^^^^^^^^^

要解决此问题,您可以使用[^)] 而不是.,就像在我的答案顶部的解决方案中一样。这样,您将只匹配单个而不是嵌套的括号集,例如 (xxx),因为在这种情况下,x 不能是 )[^)] 表示 - 除了 ) 之外的每个字符)。

【讨论】:

  • 从您的源代码中,搜索表达式应该是 \(([^)]*)\)_(.)
  • @wumpz 抱歉,什么?为什么.?我不希望 _ 之后的部分成为像 ( 这样的任何角色。 \\w\\d 在那里似乎更合适。
  • 他在他的消息来源中使用了(\\((.*?)\\)_(.)) 或者我在这里弄错了。但你是对的,如果你避免在那里匹配(。它更安全。
  • @wumpz 是的,OP 确实使用了它,但那是他/她的源代码,而不是我的(这让我在你的评论中感到困惑)。当我提出更详细的建议时,OP 也使用了.。另一点是 OP 使用带有 appendReplacement 和 appendTail 的while 循环,可以用简单的replaceAll 替换它。我意识到这可能是优化,因为在 OP 代码中只有一个 StringBuffer,但代码可读性也很重要。
  • @Pshemo,感谢您抽出宝贵时间回答。我明白为什么它现在奇怪地转换了。但是,我之所以使用 .也是匹配嵌套括号。现在我意识到那是行不通的。您是否也知道如何匹配嵌套括号?因为 [^)] 不会匹配嵌套的括号。谢谢。
猜你喜欢
  • 2023-04-04
  • 1970-01-01
  • 2011-06-17
  • 2020-07-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多