Java 使用正则表达式匹配字符串中的参数值

Java 使用正则表达式匹配字符串中的参数值,java,regex,escaping,Java,Regex,Escaping,我有一个包含多个参数的字符串,例如 PARAM1="someValue", PARAM2="someOtherValue"... 对于日志输出,我想“隐藏”一些参数值,即用***替换它们 我使用以下正则表达式来匹配参数值,这在大多数情况下都适用: (PARMANAME=")[\w\s]*" 但是,这个正则表达式只匹配单词和空格字符。我想扩展它以匹配两个引号之间的所有字符。问题是,值本身可能包含(转义)引号,例如: PARAM="the name of this param is \"para

我有一个包含多个参数的字符串,例如

PARAM1="someValue", PARAM2="someOtherValue"...
对于日志输出,我想“隐藏”一些参数值,即用***替换它们

我使用以下正则表达式来匹配参数值,这在大多数情况下都适用:

(PARMANAME=")[\w\s]*"
但是,这个正则表达式只匹配单词和空格字符。我想扩展它以匹配两个引号之间的所有字符。问题是,值本身可能包含(转义)引号,例如:

PARAM="the name of this param is \"param\""
我怎样才能正确地匹配(和替换)它

我的Java方法如下所示:

/**
 * @param input input string
 * @param params list of parameters to hide
 * @return string with the value of the parameter being replace by ***
 */
public static String hideParamValue(String input, final String... params)
{
    for (String param : params)
    {
        input = input.replaceAll("(" + param + "=)\\\"[\\w\\s]*\\\"", "$1***");
    }
    return input;
}

请尝试以下正则表达式:

PARAM="(?:[^"\\]|\\")*"

这只允许除
\
\”
之外的任何字符序列。如果您想允许除
\“
以外的其他转义序列,您可以使用
\[“rnt…]
对其进行扩展,例如,还允许
\r
\n
\t
等。您必须将转义双引号添加到匹配字符表达式中:

PARAM="(?:[^"\\]|\\")*"
[\w\s\\“]
而不是
[\w\s]
,在字符串中转义的结果将是
[\\w\\s\\\']
而不是
[\\w\\s]

因此,最终代码的结果如下

/**
 * @param input input string
 * @param params list of parameters to hide
 * @return string with the value of the parameter being replace by ***
 */
public static String hideParamValue(String input, final String... params) {
    for (String param : params)
    {
        input = input.replaceAll("(" + param + "=)\\\"[\\w\\s\\\\\"]*\\\"", "$1***");
    }
    return input;
}
A在这种情况下可能有用:

(PARAMNAME=").*?(?<!\\)"

(PARAMNAME=“).*?(?表示
前面没有
\
,因此
*?(?其中
前面没有

转义引号在Java中是一个真正的PITA,但这应该可以做到:

public class Test
{
  public static String hideParamValue(String input, final String... params)
  {
    for (String param : params)
    {
      input = input.replaceAll(
        "(" + param + "=)\"(?:[^\"\\\\]|\\\\.)*\"",
        "$1***");
    }
    return input;
  }

  public static void main(String[] args)
  {
    String s = "PARAM1=\"a b c\", PARAM2=\"d \\\"e\\\" f\", PARAM3=\"g h i\"";
    System.out.println(s);
    System.out.println(hideParamValue(s, "PARAM2", "PARAM3"));
  }
}
输出:

PARAM1="a b c", PARAM2="d \"e\" f", PARAM3="g h i"
PARAM1="a b c", PARAM2=***, PARAM3=***
[^\“\\\]
匹配除引号或反斜杠以外的任何一个字符。反斜杠必须用另一个反斜杠转义,然后每个反斜杠都必须转义为字符串文字。但引号在正则表达式中没有特殊意义,因此它只需要一个反斜杠

(?:[^\“\\\]\\\\\)
匹配除引号或反斜杠或反斜杠后跟任何内容之外的任何内容。这将照顾到转义引号,并允许转义反斜杠和其他转义序列,无需额外费用


@axtavt建议的反向查找方法只处理转义引号,它将
\\\“
视为后跟转义引号的反斜杠,而它很可能是后跟引号的转义反斜杠。

感谢所有好的答案。它们对于我的测试用例都很有效。