我有一个字符串,它包含几个“value = [something]”部分。我需要编写一个正则表达式(PCRE),只有当“value”始终具有相同的值时才会成功。例如,字符串“value =”出现n次,如果值始终为“cat”,则成功,但如果找到“cat”以外的其他内容则失败。
我的尝试到目前为止写了一个正则表达式。我的方法是捕获“value =”的第一个值然后以某种方式匹配所有其他“value =”s,但我似乎无法找到一种工作方法。 当然我不知道它的价值是什么,这就是我必须抓住它的原因。
必须成功:
aaaaaaa bbbbb value=cat cccccc ddddd value=cat fffffff value=cat ggggg hh jjj value=cat kkkkk
必须失败:
aaaaaaa bbbbb value=cat cccccc ddddd value=cat fffffff value=bat ggggg hh jjj value=cat kkkkk
对于过于复杂的解释感到抱歉。
编辑:可能我应该已经提到过这个,但我限制了我可以使用的东西。在这个自定义环境中,除了PCRE之外我不能使用任何其他东西,甚至有一些自定义限制,例如我不能使用条件组。
答案 0 :(得分:2)
不是纯正则表达式解决方案,但可能有用作为解决方法
$ grep -oE 'value=\w+' pass | uniq | awk 'END{exit NR>1?1:0}'; echo $?
0
$ grep -oE 'value=\w+' fail | uniq | awk 'END{exit NR>1?1:0}'; echo $?
1
将您的示例输入用于传递和失败文件。
$ head pass fail
==> pass <==
aaaaaaa bbbbb value=cat cccccc ddddd value=cat fffffff value=cat ggggg hh jjj value=cat kkkkk
==> fail <==
aaaaaa bbbbb value=cat cccccc ddddd value=cat fffffff value=bat ggggg hh jjj value=cat kkkkk
如果没有uniq
,也许会更好$ grep ... | awk 'a[$0]++>1{exit 1}'
答案 1 :(得分:1)
通过使用 if语句,您可以匹配此类输入字符串。这个想法是,如果第一组包含某些东西,它应该在消耗\1
字符串之后匹配value=
中的相同值,否则(如果是第一次出现)它匹配并捕获方程的右侧作为第一组。
正则表达式:
^(?:(?!value).|value=(?(1)\1(?!\S)|(\S++)))++$
注意:如果应该将多行作为输入传递,则应设置m
修饰符。
说明:
^ # Assert beginning of line
(?: # Start of non-capturing group (a)
(?!value). # If we are not hitting a `value=...` token, consume one character
| # Else
value= # Match `value=`
(?(1) # If first capturing group is set
\1(?!\S) # Next characters should be a back-reference to it
| # Else
(\S++) # Capture its value for the first time
) # End of if conditional
)++ # As much as possible (possessively) - non-empty line, end of non-capturing group (a)
$ # Assert end of line
如果value
部分是真实的,或者如果要使用相似的单词,那么下面的方法几乎要快得多,在谈论性能方面:
^(?:[^v\v]+(?!value).|value=(?(1)\1(?!\S)|(\S++)))++$
答案 2 :(得分:1)
这是一个解决方案(很长很难看)
^(?:[^v]|v(?!a)|va(?!l)|val(?!u)|valu(?!e)|value(?!=))*value=(\S+)((?:[^v]|v(?!a)|va(?!l)|val(?!u)|valu(?!e)|value(?!=))*value=(\1))*(?:[^v]|v(?!a)|va(?!l)|val(?!u)|valu(?!e)|value(?!=))*$
解决方案的关键部分是重复三次子表达式以捕获value=
:
(?:[^v]|v(?!a)|va(?!l)|val(?!u)|valu(?!e)|value(?!=))
这允许我们放置^
和$
锚点来捕获模式匹配部分之前或之后的无效输入。
匹配的核心是在(\S+)
的第一场比赛后捕捉value=
,然后在后续比赛中将该捕捉用作(\1)
。
答案 3 :(得分:0)
这在ES6fiddle.net上对我有用。它不是很优雅,但确实可以完成工作。祝你好运!
let arr = "aaaaaaa bbbbb value=cat cccccc ddddd value=cat fffffff value=cat ggggg hh jjj value=cat kkkkk".toLowerCase().split(" ").sort();
function vKeeper(e,i,a){
if(a[i].charAt(0) !== "v"){
a[i] = "";
}
}
function vStripper(e,i,a){
a[i] = a[i].replace("value=","");
}
arr.forEach(vKeeper);
arr.forEach(vStripper);
while(arr[0] === ""){
arr.shift();
}
var res = false;
while(arr[0] === arr[arr.length-1]){
if(arr.length === 1){
res = true
break;
} else {
arr.pop()
}
}
console.log(res);