简体   繁体   中英

Multiple regex matches in single expression

I have the following sensitive data:

"Password":"123","RootPassword":"123qwe","PassPhrase":"phrase"

I would like to get the following safe data:

"Password":"***","RootPassword":"***","PassPhrase":"***"

It's my code:

internal class Program
{
    private static void Main(string[] args)
    {
        var data = "\"Password\":\"123\",\"RootPassword\":\"123qwe\",\"PassPhrase\":\"phrase\"";

        var safe1 = PasswordReplacer.Replace1(data);
        var safe2 = PasswordReplacer.Replace2(data);
    }
}

public static class PasswordReplacer
{
    private const string RegExpReplacement = "$1***$2";
    private const string Template = "(\"{0}\":\").*?(\")";

    private static readonly string[] PasswordLiterals =
    {
        "password",
        "RootPassword",
        "PassPhrase"
    };

    public static string Replace1(string sensitiveInfo)
    {
        foreach (var literal in PasswordLiterals)
        {
            var pattern = string.Format(Template, literal);
            var regex = new Regex(pattern, RegexOptions.IgnoreCase);
            sensitiveInfo = regex.Replace(sensitiveInfo, RegExpReplacement);
        }

        return sensitiveInfo;
    }
    
    public static string Replace2(string sensitiveInfo)
    {
       var multiplePattern = "(\"password\":\")|(\"RootPassword\":\")|(\"PassPhrase\":\").*?(\")"; //?
        var regex = new Regex(string.Format(Template, multiplePattern), RegexOptions.IgnoreCase);
        return regex.Replace(sensitiveInfo, RegExpReplacement);
    }
}

Replace1 method works as expected. But it does it one by one. My question is is it possble to do the same but using single regex match? If so I need help with Replace2 .

The Replace2 can look like

public static string Replace2(string sensitiveInfo)
{
    var multiplePattern = $"(\"(?:{string.Join("|", PasswordLiterals)})\":\")[^\"]*(\")"; 
    return Regex.Replace(sensitiveInfo, multiplePattern, RegExpReplacement, RegexOptions.IgnoreCase);
}

See the C# demo .

The multiplePattern will hold a pattern like ("(?:password|RootPassword|PassPhrase)":")[^"]*(") , see the regex demo . Quick details:

  • ("(?:password|RootPassword|PassPhrase)":") - Group 1 ( $1 ): a " char followed with either password , RootPassword or PassPhrase and then a ":" substring
  • [^"]* - any zero or more chars other than " as many as possible
  • (") - Group 2 ( $2 ): a " char.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM