匹配字符串运算符的正则表达式
Regular expression to match string operator
我正在尝试创建一个匹配运算符 ^ (xor) 的正则表达式,只要它充当两个字符串之间的运算符而不是字符串的一部分。
例如,有一个包含这两行的文件:
'asdfasdf'; 'asdfasd'^'asdflkj';
['asdf', '^', 'asdf'];
只有第一个应该匹配,因为它是唯一一个 ^ 不属于字符串的一部分。当 ^ 不在字符串中时,如何创建正则表达式来匹配它?
更新: 我正在使用 egrep。我需要一种方法来确定 ^ 何时是字符串的一部分或何时不是。我最后的 objective 是查找何时对字符串使用 xor 运算符:类似于
('[^']'\^.+|.+\^'[^']')
但这与我示例的第二行匹配。
所以,它应该匹配如下字符串:
'asdf1524-sdfaA'^'sdfa322='
'sdfa22_'^$myvar
$myvar^'asAf34%'
但是 它不应该匹配:
['+','*','^','%']
'^'=>2
"afa^sadfa"
UPDATE2:添加了一个示例来说明为什么建议的 awk 解决方案不起作用。使用单引号字符串操作时,我需要找到 ^
运算符。我想在一个文件中找到它出现的次数,我想在 bash 脚本中添加这个检查。
提前致谢!
像这样:^[^^,]+?(?<!')'?\^'?(?!')[^^,]+?$
应该做你想做的事。提供了一个示例 here.
你想做的是明确地捕捉可能包含你的^
字符串't 想要匹配然后丢弃该字符串。这个解释的很透彻here and with a JavaScript example here.
如果您正在使用 PCRE 正则表达式,您可以利用 PCRE 的 (*SKIP)(*FAIL)
选项立即丢弃有问题的匹配项,否则您必须将它们捕获到一个捕获组中,然后您可以检查并丢弃整个匹配是捕获组不为空。
这将是 Regex101 demo
的 PCRE 方式
(?:(['"])(?:(?!|\).|\.)*|\/\/[^\n]*(?:\n|$)|\/\*(?:[^*]|\*(?!\/))*\*\/)(*SKIP)(*FAIL)|\^
如果您需要根据捕获组手动丢弃匹配项,请执行以下操作:
((['"])(?:(?!|\).|\.)*|\/\/[^\n]*(?:\n|$)|\/\*(?:[^*]|\*(?!\/))*\*\/)|\^
另见 Debuggex Demo,其中 ^
的你 do 想要匹配是黄色的,表示他们不在捕获组中。所有其他匹配项都有一个捕获组,并在 Debuggex 视觉对象中以较暗的颜色突出显示。
注意: 我添加了对 /*...*/
和 //
注释的支持,但这些都没有解释 [=49] 中的 Heredoc/nowdoc 字符串=],不知道这对你是否重要,你可以将它添加为另一个替代匹配相当简单,应该 (*SKIP)(*FAIL)
ed 或捕获并丢弃。
只需将 awk 与字段和普通正则表达式一起使用,而不是将 grep 与复杂的正则表达式一起使用,例如使用该线程中迄今为止建议的所有示例输入:
$ cat file
'asdfasdf'; 'asdfasd'^'asdflkj'; YES
['asdf', '^', 'asdf']; NO
''o'^'o'' NO
'asdf1524-sdfaA'^'sdfa322=' YES
'sdfa22_'^$myvar YES
$myvar^'asAf34%' YES
['+','*','^','%'] NO
'^'=>2 NO
'asdfa5A_sdf'; 'asd5A_fasd'^'asd5A_flkj'; YES
'asdfa5A_'^$var1; YES
$var2^'asdfa5A_'; YES
'asdf', '^', 'asdf'; NO
'+', '-', '*', '/', '^', '_'); NO
'+'=>0,'-'=>0,'*'=>0,'/'=>0,'^'=>1); NO
'+'=>0,'-'=>0,'*'=>1,'/'=>1,'_'=>1,'^'=>2); NO
'+', '-', '*', '/', '^'))) { NO
$ awk -F"'" '{for (i=1;i<=NF;i+=2) if ($i ~ /\^/) {print; next}}' file
'asdfasdf'; 'asdfasd'^'asdflkj'; YES
'asdf1524-sdfaA'^'sdfa322=' YES
'sdfa22_'^$myvar YES
$myvar^'asAf34%' YES
'asdfa5A_sdf'; 'asd5A_fasd'^'asd5A_flkj'; YES
'asdfa5A_'^$var1; YES
$var2^'asdfa5A_'; YES
上面的工作是将每个 '
处的每一行分成一系列字段,因此奇数字段在引号对之外,而偶数字段在引号对内(例如 out'in'out'in'out
) 然后您只需在奇数字段中查找 ^
。
这需要做更多的工作来处理字符串中的换行符 and/or 转义引号(如果可能的话),但到那时你真的应该查看语言解析器而不是 shell 脚本。
我需要在 grep 中使用它,所以 pcre 无法正常工作(即使使用 pgrep)。
我最终使用了一个非常丑陋且并不总是有效的正则表达式:
^[^']*((('[^']*){1}|('[^']*){3}|('[^']*){5}|('[^']*){7}|('[^']*){9}|('[^']*){11})[^']+'\^.+|(('[^']*){0}|('[^']*){2}|('[^']*){4}|('[^']*){6}|('[^']*){8}|('[^']*){10})[^']+\^'.+)
这适用于在运算符之前声明的最多 5 个字符串,并最终比较 [^']+\^'.+
或 [^']+'\^.+
。我知道,我知道......但这是我发现让它工作的唯一方法,当然只适用于单引号字符串。
它与此示例文件完美配合:
'asdfa5A_sdf'; 'asd5A_fasd'^'asd5A_flkj';
'asdfa5A_'^$var1;
$var2^'asdfa5A_';
'asdf', '^', 'asdf';
'+', '-', '*', '/', '^', '_');
'+'=>0,'-'=>0,'*'=>0,'/'=>0,'^'=>1);
'+'=>0,'-'=>0,'*'=>1,'/'=>1,'_'=>1,'^'=>2);
'+', '-', '*', '/', '^'))) {
欢迎更好的解决方案:)。
感谢所有帮助过我的人,特别感谢@npinti,他花了很多时间检查这个!
我正在尝试创建一个匹配运算符 ^ (xor) 的正则表达式,只要它充当两个字符串之间的运算符而不是字符串的一部分。
例如,有一个包含这两行的文件:
'asdfasdf'; 'asdfasd'^'asdflkj';
['asdf', '^', 'asdf'];
只有第一个应该匹配,因为它是唯一一个 ^ 不属于字符串的一部分。当 ^ 不在字符串中时,如何创建正则表达式来匹配它?
更新: 我正在使用 egrep。我需要一种方法来确定 ^ 何时是字符串的一部分或何时不是。我最后的 objective 是查找何时对字符串使用 xor 运算符:类似于
('[^']'\^.+|.+\^'[^']')
但这与我示例的第二行匹配。
所以,它应该匹配如下字符串:
'asdf1524-sdfaA'^'sdfa322='
'sdfa22_'^$myvar
$myvar^'asAf34%'
但是 它不应该匹配:
['+','*','^','%']
'^'=>2
"afa^sadfa"
UPDATE2:添加了一个示例来说明为什么建议的 awk 解决方案不起作用。使用单引号字符串操作时,我需要找到 ^
运算符。我想在一个文件中找到它出现的次数,我想在 bash 脚本中添加这个检查。
提前致谢!
像这样:^[^^,]+?(?<!')'?\^'?(?!')[^^,]+?$
应该做你想做的事。提供了一个示例 here.
你想做的是明确地捕捉可能包含你的^
字符串't 想要匹配然后丢弃该字符串。这个解释的很透彻here and with a JavaScript example here.
如果您正在使用 PCRE 正则表达式,您可以利用 PCRE 的 (*SKIP)(*FAIL)
选项立即丢弃有问题的匹配项,否则您必须将它们捕获到一个捕获组中,然后您可以检查并丢弃整个匹配是捕获组不为空。
这将是 Regex101 demo
的 PCRE 方式(?:(['"])(?:(?!|\).|\.)*|\/\/[^\n]*(?:\n|$)|\/\*(?:[^*]|\*(?!\/))*\*\/)(*SKIP)(*FAIL)|\^
如果您需要根据捕获组手动丢弃匹配项,请执行以下操作:
((['"])(?:(?!|\).|\.)*|\/\/[^\n]*(?:\n|$)|\/\*(?:[^*]|\*(?!\/))*\*\/)|\^
另见 Debuggex Demo,其中 ^
的你 do 想要匹配是黄色的,表示他们不在捕获组中。所有其他匹配项都有一个捕获组,并在 Debuggex 视觉对象中以较暗的颜色突出显示。
注意: 我添加了对 /*...*/
和 //
注释的支持,但这些都没有解释 [=49] 中的 Heredoc/nowdoc 字符串=],不知道这对你是否重要,你可以将它添加为另一个替代匹配相当简单,应该 (*SKIP)(*FAIL)
ed 或捕获并丢弃。
只需将 awk 与字段和普通正则表达式一起使用,而不是将 grep 与复杂的正则表达式一起使用,例如使用该线程中迄今为止建议的所有示例输入:
$ cat file
'asdfasdf'; 'asdfasd'^'asdflkj'; YES
['asdf', '^', 'asdf']; NO
''o'^'o'' NO
'asdf1524-sdfaA'^'sdfa322=' YES
'sdfa22_'^$myvar YES
$myvar^'asAf34%' YES
['+','*','^','%'] NO
'^'=>2 NO
'asdfa5A_sdf'; 'asd5A_fasd'^'asd5A_flkj'; YES
'asdfa5A_'^$var1; YES
$var2^'asdfa5A_'; YES
'asdf', '^', 'asdf'; NO
'+', '-', '*', '/', '^', '_'); NO
'+'=>0,'-'=>0,'*'=>0,'/'=>0,'^'=>1); NO
'+'=>0,'-'=>0,'*'=>1,'/'=>1,'_'=>1,'^'=>2); NO
'+', '-', '*', '/', '^'))) { NO
$ awk -F"'" '{for (i=1;i<=NF;i+=2) if ($i ~ /\^/) {print; next}}' file
'asdfasdf'; 'asdfasd'^'asdflkj'; YES
'asdf1524-sdfaA'^'sdfa322=' YES
'sdfa22_'^$myvar YES
$myvar^'asAf34%' YES
'asdfa5A_sdf'; 'asd5A_fasd'^'asd5A_flkj'; YES
'asdfa5A_'^$var1; YES
$var2^'asdfa5A_'; YES
上面的工作是将每个 '
处的每一行分成一系列字段,因此奇数字段在引号对之外,而偶数字段在引号对内(例如 out'in'out'in'out
) 然后您只需在奇数字段中查找 ^
。
这需要做更多的工作来处理字符串中的换行符 and/or 转义引号(如果可能的话),但到那时你真的应该查看语言解析器而不是 shell 脚本。
我需要在 grep 中使用它,所以 pcre 无法正常工作(即使使用 pgrep)。 我最终使用了一个非常丑陋且并不总是有效的正则表达式:
^[^']*((('[^']*){1}|('[^']*){3}|('[^']*){5}|('[^']*){7}|('[^']*){9}|('[^']*){11})[^']+'\^.+|(('[^']*){0}|('[^']*){2}|('[^']*){4}|('[^']*){6}|('[^']*){8}|('[^']*){10})[^']+\^'.+)
这适用于在运算符之前声明的最多 5 个字符串,并最终比较 [^']+\^'.+
或 [^']+'\^.+
。我知道,我知道......但这是我发现让它工作的唯一方法,当然只适用于单引号字符串。
它与此示例文件完美配合:
'asdfa5A_sdf'; 'asd5A_fasd'^'asd5A_flkj';
'asdfa5A_'^$var1;
$var2^'asdfa5A_';
'asdf', '^', 'asdf';
'+', '-', '*', '/', '^', '_');
'+'=>0,'-'=>0,'*'=>0,'/'=>0,'^'=>1);
'+'=>0,'-'=>0,'*'=>1,'/'=>1,'_'=>1,'^'=>2);
'+', '-', '*', '/', '^'))) {
欢迎更好的解决方案:)。 感谢所有帮助过我的人,特别感谢@npinti,他花了很多时间检查这个!