正则表达式查找每个出现的字符串,并且它后面必须始终跟有相同的字符串
Regex find every occurence of string and it must be always followed by the same string
我有一个字符串,它包含几个 "value=[something]" 部分。我需要编写一个正则表达式 (PCRE),只有当 "value" 始终具有相同的值时它才会成功。例如在字符串中 "value=" 出现 n 次,如果值总是 "cat",则成功,但如果它找到除 "cat".
之外的其他内容,则失败
到目前为止,我尝试编写正则表达式失败了。我的方法是捕获 "value=" 的第一个值,然后以某种方式匹配所有其他 "value=",但我似乎找不到工作方法。
我当然不知道这个值是多少,所以我必须捕获它。
必须成功:
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 之外的任何其他东西,即使它有一些自定义限制,例如我不能使用条件组。
不是纯粹的正则表达式解决方案,但可能用作解决方法
$ 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[[=12=]]++>1{exit 1}'
通过使用 if 语句,您可以匹配此类输入字符串。这个想法是,如果第一组包含某些东西,它应该在使用 value=
字符串后匹配 </code> 中的相同值,否则(如果是第一次出现)它匹配并捕获等式的右侧作为第一组。 </p>
<p>正则表达式:</p>
<pre><code>^(?:(?!value).|value=(?(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
(?!\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)(?!\S)|(\S++)))++$
这是一个解决方案(很长很丑)
^(?:[^v]|v(?!a)|va(?!l)|val(?!u)|valu(?!e)|value(?!=))*value=(\S+)((?:[^v]|v(?!a)|va(?!l)|val(?!u)|valu(?!e)|value(?!=))*value=())*(?:[^v]|v(?!a)|va(?!l)|val(?!u)|valu(?!e)|value(?!=))*$
解决方案的关键部分是重复三次的子表达式以进行陷印 value=
:
(?:[^v]|v(?!a)|va(?!l)|val(?!u)|valu(?!e)|value(?!=))
这允许我们放置 ^
和 $
锚点以在模式的匹配部分之前或之后捕获无效输入。
比赛的核心是在 value=
的第一场比赛之后捕获 (\S+)
,然后在随后的比赛中使用该捕获作为 ()
。
这对我有用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);
我有一个字符串,它包含几个 "value=[something]" 部分。我需要编写一个正则表达式 (PCRE),只有当 "value" 始终具有相同的值时它才会成功。例如在字符串中 "value=" 出现 n 次,如果值总是 "cat",则成功,但如果它找到除 "cat".
之外的其他内容,则失败到目前为止,我尝试编写正则表达式失败了。我的方法是捕获 "value=" 的第一个值,然后以某种方式匹配所有其他 "value=",但我似乎找不到工作方法。 我当然不知道这个值是多少,所以我必须捕获它。
必须成功:
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 之外的任何其他东西,即使它有一些自定义限制,例如我不能使用条件组。
不是纯粹的正则表达式解决方案,但可能用作解决方法
$ 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[[=12=]]++>1{exit 1}'
通过使用 if 语句,您可以匹配此类输入字符串。这个想法是,如果第一组包含某些东西,它应该在使用 value=
字符串后匹配 </code> 中的相同值,否则(如果是第一次出现)它匹配并捕获等式的右侧作为第一组。 </p>
<p>正则表达式:</p>
<pre><code>^(?:(?!value).|value=(?(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
(?!\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)(?!\S)|(\S++)))++$
这是一个解决方案(很长很丑)
^(?:[^v]|v(?!a)|va(?!l)|val(?!u)|valu(?!e)|value(?!=))*value=(\S+)((?:[^v]|v(?!a)|va(?!l)|val(?!u)|valu(?!e)|value(?!=))*value=())*(?:[^v]|v(?!a)|va(?!l)|val(?!u)|valu(?!e)|value(?!=))*$
解决方案的关键部分是重复三次的子表达式以进行陷印 value=
:
(?:[^v]|v(?!a)|va(?!l)|val(?!u)|valu(?!e)|value(?!=))
这允许我们放置 ^
和 $
锚点以在模式的匹配部分之前或之后捕获无效输入。
比赛的核心是在 value=
的第一场比赛之后捕获 (\S+)
,然后在随后的比赛中使用该捕获作为 ()
。
这对我有用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);