使用正则表达式从键值对的值中提取子字符串
Extract a substring from value of key-value pair using regex
我在日志中有一个字符串,我想根据正则表达式屏蔽值。
例如:
"email":"testEmail@test.com", "phone":"1111111111", "text":"sample text may contain email testEmail@test.com as well"
正则表达式应该屏蔽
- email 值 - 在 "email" 和 "text"
之后的字符串中
- phone个数
期望输出:
"email":"*****", "phone":"*****", "text":"sample text may contain email ***** as well"
我能做的是单独屏蔽电子邮件和 phone,但不屏蔽 "text" 之后字符串中的电子邮件 ID。
正则表达式发展至今:
(?<=\"(?:email|phone)\"[:])(\")([^\"]*)(\")
由于您在第一部分中没有通过匹配双引号来匹配电子邮件地址,因此您也可以通过不匹配双引号来匹配文本中的电子邮件地址。
实现此目的的一种方法是使用环视和 alternation 获得匹配项。然后用 *****
替换匹配项
请注意,您不必转义双引号,冒号也可以不使用字符 class.
(?<="(?:phone|email)":")[^"]+(?=")|[^@"\s]+@[^@"\s]+
说明
(?<="(?:phone|email)":")
断言左边是 "phone":" 或 "email":"
[^"]+(?=")
不匹配双引号,确保最后有双引号
|
或
[^@"\s]+@[^@"\s]+
通过使用不匹配双引号或@ 的否定字符 class 来匹配 email like
模式
Meta Sequence Word Boundary \b
& Alternation |
输入的字符串模式有引号或 spaces 包裹在目标周围,它们都被认为是非单词。所以这个:“\b
emailPattern\b
”和这个:space\b
emailPattern\b
space 是匹配项。交替赋予一条线两条线的力量。搜索 emailPattern OR phonePattern.
/(\b\w+?@\w+?\.\w+?\b|[0-9]{10})/g;
(
字边界(左边一个非字)\b
- 一个或多个单词字符
\w+?
- 文字
@
- 一个或多个单词字符
\w+?
- 转义文字
.
- 一个或多个单词字符
\w+?
- 单词边界(右边一个非单词)
\b
- 或
|
- 10个连续数字
[0-9]{10}
)
g
局部标志在第一次匹配后继续搜索。
演示
let str = `"email":"testEmail@test.com", "phone":"1111111111", "text":"sample text may contain email testEmail@test.com as well"`;
const rgx = /(\b\w+?@\w+?\.\w+?\b|[0-9]{10})/g;
let res = str.replace(rgx, '*****');
console.log(res);
您当前的 RegEx 试图一次完成太多。您最好拆分条件并分别处理它们。我假设输入将始终遵循您示例的结构,没有边缘情况:
- 电子邮件:
\w+@.+?(?="|\s)
- 在电子邮件中,每个以 @
开头的字符始终是一个单词字符,因此使用 \w+@
足以捕获电子邮件的前半部分。至于后半部分,我使用了带有惰性量词 (+?
) 的通配符 (.
) 来尽快停止捕获,并将其与检查双引号或空格的正向前瞻相结合((?="|\s)
) 所以要捕获 "email"
和 "text"
属性中的电子邮件。 Lookarounds are zero-length assertions 因此他们不会被捕获。
- Phone个数:
(?<="phone":")\d+
- 这里我只是在回顾中使用前缀 "phone":"
然后只捕获数字 \d+
.
结合这两个条件,您就有了 RegEx:\w+@.+?(?="|\s)|(?<="phone":")\d+
.
Regex101: https://regex101.com/r/UvDIjI/3
我在日志中有一个字符串,我想根据正则表达式屏蔽值。
例如:
"email":"testEmail@test.com", "phone":"1111111111", "text":"sample text may contain email testEmail@test.com as well"
正则表达式应该屏蔽
- email 值 - 在 "email" 和 "text" 之后的字符串中
- phone个数
期望输出:
"email":"*****", "phone":"*****", "text":"sample text may contain email ***** as well"
我能做的是单独屏蔽电子邮件和 phone,但不屏蔽 "text" 之后字符串中的电子邮件 ID。
正则表达式发展至今:
(?<=\"(?:email|phone)\"[:])(\")([^\"]*)(\")
由于您在第一部分中没有通过匹配双引号来匹配电子邮件地址,因此您也可以通过不匹配双引号来匹配文本中的电子邮件地址。
实现此目的的一种方法是使用环视和 alternation 获得匹配项。然后用 *****
请注意,您不必转义双引号,冒号也可以不使用字符 class.
(?<="(?:phone|email)":")[^"]+(?=")|[^@"\s]+@[^@"\s]+
说明
(?<="(?:phone|email)":")
断言左边是 "phone":" 或 "email":"[^"]+(?=")
不匹配双引号,确保最后有双引号|
或[^@"\s]+@[^@"\s]+
通过使用不匹配双引号或@ 的否定字符 class 来匹配
email like
模式
Meta Sequence Word Boundary \b
& Alternation |
输入的字符串模式有引号或 spaces 包裹在目标周围,它们都被认为是非单词。所以这个:“\b
emailPattern\b
”和这个:space\b
emailPattern\b
space 是匹配项。交替赋予一条线两条线的力量。搜索 emailPattern OR phonePattern.
/(\b\w+?@\w+?\.\w+?\b|[0-9]{10})/g;
(
字边界(左边一个非字)\b
- 一个或多个单词字符
\w+?
- 文字
@
- 一个或多个单词字符
\w+?
- 转义文字
.
- 一个或多个单词字符
\w+?
- 单词边界(右边一个非单词)
\b
- 或
|
- 10个连续数字
[0-9]{10}
)
g
局部标志在第一次匹配后继续搜索。
演示
let str = `"email":"testEmail@test.com", "phone":"1111111111", "text":"sample text may contain email testEmail@test.com as well"`;
const rgx = /(\b\w+?@\w+?\.\w+?\b|[0-9]{10})/g;
let res = str.replace(rgx, '*****');
console.log(res);
您当前的 RegEx 试图一次完成太多。您最好拆分条件并分别处理它们。我假设输入将始终遵循您示例的结构,没有边缘情况:
- 电子邮件:
\w+@.+?(?="|\s)
- 在电子邮件中,每个以@
开头的字符始终是一个单词字符,因此使用\w+@
足以捕获电子邮件的前半部分。至于后半部分,我使用了带有惰性量词 (+?
) 的通配符 (.
) 来尽快停止捕获,并将其与检查双引号或空格的正向前瞻相结合((?="|\s)
) 所以要捕获"email"
和"text"
属性中的电子邮件。 Lookarounds are zero-length assertions 因此他们不会被捕获。
- Phone个数:
(?<="phone":")\d+
- 这里我只是在回顾中使用前缀"phone":"
然后只捕获数字\d+
.
结合这两个条件,您就有了 RegEx:\w+@.+?(?="|\s)|(?<="phone":")\d+
.
Regex101: https://regex101.com/r/UvDIjI/3