有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

Java中的正则表达式不工作,而同一正则表达式在shell中工作

我想用${variable}$替换所有:variable(单词以:开头)

比如

  • :aks_num${aks_num}$

  • :brn_num${brn_num}$

以下是我的代码,它不起作用:

public static void main(String[] argv) throws Exception 
{
    CharSequence chSeq = "AND ((:aks_num = -1) OR (aks_num = :aks_num AND ((:brn_num = -1) OR (brn_num = :brn_num))))";

    // replaceAll also not working
    //String s = chSeq.replaceAll(":\\([a-z_]*\\)","\\${ $1 \\}$");

    Pattern p = Pattern.compile(":\\([a-z_]*\\)");
    Matcher m = p.matcher(chSeq);

    if (m.find()) {
         System.out.println("Found value: " + m.group(0) );
         System.out.println("Found value: " + m.group(1) );
         System.out.println("Found value: " + m.group(2) );
      } else {
         System.out.println("NO MATCH");
      }
}

在shell脚本中,以下正则表达式可以完美地工作:

s/:\([a-z_]*\)/${\1}$/g

共 (4) 个答案

  1. # 1 楼答案

    我相信您对Java的正则表达式语法感到困惑,它不同于常规的sed语法。无需对括号进行转义即可使其成为“特殊”分组运算符。反之亦然,在Java中,当您转义括号时,它们开始匹配文字()符号

    在替换模式中,regex引擎必须转义$才能替换为文字$符号,但不需要在那里转义大括号

    所以,只要使用

    .replaceAll(":([a-z_]+)", "\\${$1}\\$")
    

    IDEONE demo

    我建议使用+量词,因为我怀疑您是否需要匹配:后跟空格或数字——任何非字母

    顺便说一句,Java中不需要任何/g标志,因为replaceAll将用提供的替换模式替换所有匹配项

    注意:您可以进一步调整模式,使所有字母/数字/下划线与":(\\w+)"匹配。或者只是字母数字/下划线:":([\\p{Alnum}_]+)"

  2. # 2 楼答案

    CharSequence chSeq = "AND ((:aks_num = -1) OR (aks_num = :aks_num AND ((:brn_num = -1) OR (brn_num = :brn_num))))";
    
    // replaceAll also not working
    //String s = chSeq.replaceAll(":\\([a-z_]*\\)","\\${ $1 \\}$");
    
    Pattern p = Pattern.compile(":(\\w+)");
    Matcher m = p.matcher(chSeq);
    
    while (m.find()) {
         System.out.println("Found value: " + m.group(1) );
    }
    

    Ideone Demo

    replaceAll配合良好

    Pattern p = Pattern.compile("(:\\w+)");
    Matcher m = p.matcher(x);
    x = m.replaceAll("\\${$1}\\$");
    
  3. # 3 楼答案

    :\\([a-z_]*\\)(带转义括号)表示要匹配:(aks_num)之类的表达式。显然,输入字符串中没有这样的表达式。这就解释了为什么没有匹配项

    相反,如果要使用括号来捕获某些变量,则不应转义括号

    例如:

    CharSequence chSeq = "AND ((:aks_num = -1) OR (aks_num = :aks_num AND ((:brn_num = -1) OR (brn_num = :brn_num))))";
    Pattern p = Pattern.compile(":([a-z_]*)");
    Matcher m = p.matcher(chSeq);
    
    while (m.find()) {
      System.out.println("Found value: " + m.group(0)+". Captured : "+m.group(1));
    }
    

    输出:

    Found value: :aks_num. Captured : aks_num
    Found value: :aks_num. Captured : aks_num
    Found value: :brn_num. Captured : brn_num
    Found value: :brn_num. Captured : brn_num
    
  4. # 4 楼答案

    你不需要跳过括号,所以

    Pattern.compile(":([a-z_]*)");
    

    应该有用