正则表达式 JSON 字符串掩码

huangapple go评论61阅读模式
英文:

Regex JSON String Mask

问题

你可以使用以下正则表达式来处理这个情况:

String s = "{ \"Name1\":\"Jo\", \"pass\":\"123456789123\" }";

System.out.println(s
        .replaceAll("(?<=Name1\":\")(.{1,5})(.*?)", "*****$2")
        .replaceAll("(?<=pass\":\")(.{1,5})(.*?)", "*****$2")
);

这将确保即使 "Name1" 的长度少于 5 个字符,也会在其后添加逗号。

英文:

I am using the following code to mask first 5 chars of JSON Value and it works as expected.

String s = &quot;{ \&quot;Name1\&quot;:\&quot;Cristhoper David\&quot;, \&quot;pass\&quot;:\&quot;123456789123\&quot; }&quot;;

System.out.println(s
        .replaceAll(&quot;(?&lt;=Name1\&quot;:\&quot;)(.{1,5})(.*?)&quot;, &quot;*****$2&quot;)
        .replaceAll(&quot;(?&lt;=pass\&quot;:\&quot;)(.{1,5})(.*?)&quot;, &quot;*****$2&quot;)
);

Output:

{ &quot;Name1&quot;:&quot;*****hoper David&quot;, &quot;pass&quot;:&quot;*****6789123&quot; }

But when the Name1 is less than 5 chars the JSON is getting improper and &quot; and , signs are getting disappeared as in following example:

String s = &quot;{ \&quot;Name1\&quot;:\&quot;Joe\&quot;, \&quot;pass\&quot;:\&quot;123456789123\&quot; }&quot;;

System.out.println(s
        .replaceAll(&quot;(?&lt;=Name1\&quot;:\&quot;)(.{1,5})(.*?)&quot;, &quot;*****$2&quot;)
        .replaceAll(&quot;(?&lt;=pass\&quot;:\&quot;)(.{1,5})(.*?)&quot;, &quot;*****$2&quot;)
);

Output:

{ &quot;Name1&quot;:&quot;***** &quot;pass&quot;:&quot;*****6789123&quot; }

Here &quot; and , got removed.

And for the following as well

String s = &quot;{ \&quot;Name1\&quot;:\&quot;Jo\&quot;, \&quot;pass\&quot;:\&quot;123456789123\&quot; }&quot;;

System.out.println(s
        .replaceAll(&quot;(?&lt;=Name1\&quot;:\&quot;)(.{1,5})(.*?)&quot;, &quot;*****$2&quot;)
        .replaceAll(&quot;(?&lt;=pass\&quot;:\&quot;)(.{1,5})(.*?)&quot;, &quot;*****$2&quot;)
);

Output:

{ &quot;Name1&quot;:&quot;*****&quot;pass&quot;:&quot;*****6789123&quot; }

If Name1 is less than 5 chars I want it to be

{ &quot;Name1&quot;:&quot;*****&quot;,&quot;pass&quot;:&quot;*****6789123&quot; }

How should I correct my regex to handle this?

答案1

得分: 1

初始问题:

将值的前5个字符替换为掩码,并且如果值少于5个字符,仍然用5个字符的常量替换。OP希望在以后的阶段为JsonXML执行此操作。


实际问题:

通过评论变得清楚,OP实际上希望替换XML字符串中值的前5个字符。因此,请尝试:

(?<=<(?:Name1|pass)>[^<]{0,4})[^<]

在线演示请查看这里

  • (?<= - 打开正向回顾后查找;
    • (?:Name1|pass) - 非捕获组,匹配文字'Name1'或'pass';
    • >[^<]{0,4}) - 匹配文字'>'和在关闭回顾前的0-4个非'<'字符;
  • [^<] - 匹配单个非'<'字符。

相同的技术可以应用于Json字符串:

(?<="(?:Name1|pass)":"[^"]{0,4})[^"]

或者,稍微宽松一点,但现在可能已足够的选项混合:

(?<=[<"](?:Name1|pass)(>|":"[^<"]{0,4})[^<"]
英文:

Initial question:

Mask first 5 characters of value and if value is less than 5 characters, still replace with a constant of 5 characters. OP wanted this done for Json and XML in a later stage.


Actual question:

It became clear through the comments that OP is actually looking to replace up to the first 5 characters of a value within XML-string. Therefor try:

(?&lt;=&lt;(?:Name1|pass)&gt;[^&lt;]{0,4})[^&lt;]

See an online demo

  • (?&lt;= - Open positive lookbehind;
    • (?:Name1|pass) - Non-capture group to match either 'Name1' or 'pass' literally;
    • &gt;[^&lt;]{0,4}) - Match a literal '>' and 0-4 characters other than '<' before we close the lookbehind;
  • [^&lt;] - Match a single character other than '<'.

The same technique could be applied for a Json-string:

(?&lt;=\&quot;(?:Name1|pass)\&quot;:\&quot;[^\&quot;]{0,4})[^\&quot;]

Or, a little less strict, but probably good enough for now, a mix of both options:

(?&lt;=[&lt;\&quot;](?:Name1|pass)(?:&gt;|\&quot;:\&quot;)[^&lt;\&quot;]{0,4})[^&lt;\&quot;]

答案2

得分: 0

被添加的模式 |(?&lt;=Name1\&quot;:\)(.+?)&quot; 匹配了 Name1 字段少于 5 个字符的情况。 .+? 表示一个或多个字符。

英文:

The added pattern |(?&lt;=Name1\&quot;:\)(.+?)&quot;matches the case where Name1 has fewer than 5 characters. The .+?means one or more characters.

答案3

得分: 0

你可以通过将你的正则表达式更改为以下方式来解决这个问题:

(?<=Name1\"):([^"]{1,5})(.*?)

  • . 匹配任何字符
  • [^"] 匹配除了 " 之外的所有字符。
    因此它会停在名称后面的 "
    所选组 ($1) 可以包含 1 到 5 个字符。
    如果 Name1"",那么输出中也将是 ""

顺便说一下:你在 "pass" 上也有相同的问题。

你的代码应该如下所示:

System.out.println(s.
                   replaceAll("(?<=Name1\"):([^\"]{1,5})(.*?)", "*****$2").
                   replaceAll("(?<=pass\"):([^\"]{1,5})(.*?)",  "*****$2")
                  );

查看 regex101

英文:

You can solve this if you change your regex like this

(?&lt;=Name1\&quot;:\&quot;)([^&quot;]{1,5})(.*?)

  • . matches any character
  • [^&quot;] matches all but &quot;.
    So it will stop at the &quot; after the name.
    The selected group ($1) then can have 1..5 characters.
    If Name1 is &quot;&quot;, then it will be &quot;&quot; in the output too.

By the way: you have the same problem with "pass".

Your code shoud look like:

System.out.println(s.
                   replaceAll(&quot;(?&lt;=Name1\&quot;:\&quot;)([^\&quot;]{1,5})(.*?)&quot;, &quot;*****$2&quot;).
                   replaceAll(&quot;(?&lt;=pass\&quot;:\&quot;)([^\&quot;]{1,5})(.*?)&quot;,  &quot;*****$2&quot;)
                  );

Look at regex101

huangapple
  • 本文由 发表于 2023年4月19日 15:21:25
  • 转载请务必保留本文链接:https://go.coder-hub.com/76051735.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定