我有一个正则表达式来查找文件中的函数。
See how expression perfectly works in PHP
如果我尝试使用来自控制台的grep运行相同的正则表达式,我会收到错误:
grep -rP "(_t\s*\(\s*([\'\"])(\d+)\2\s*,\s*([\'\"])(.*?)(?<!\\)\4\s*(?(?=,)[^\)]*\s*\)|\)))" application scripts library public data | sort -n | uniq
grep: unrecognized character after (?<
看起来grep
无法处理这部分正则表达式(?<!\\)
,这对我很重要。
有人可以建议如何修改正则表达式以使grep
与它一起使用吗?
编辑:
字符串:_t('123', 'pcs.', '', $userLang) . $data['ticker'] . ' (' . $data['security_name'] . ')
需要找到:
功能索引(&#39; 123&#39;)
功能中的文字(&#39; pcs。&#39;)
功能本身
> _t('123', 'pcs.', '', $userLang)
答案 0 :(得分:3)
执行我在评论中所说的内容可以解决您的问题(使用链接中的数据):
$ cat file
_t('123', 'шт.', '', $userLang) . $data['ticker'] . ' (' . $data['security_name'] . ')
$ grep -P '(_t\s*\(\s*(['"'"'"])(\d+)\2\s*,\s*(['"'"'"])(.*?)(?<!\\)\4\s*(?(?=,)[^\)]*\s*\)|\)))' file
_t('123', 'шт.', '', $userLang) . $data['ticker'] . ' (' . $data['security_name'] . ')
这里的技巧是在整个正则表达式周围使用单引号,然后每当你想要单引号时,执行'"'"'
,这意味着&#34;关闭原始字符串,在双引号内添加单引号,然后打开一个新的单引号字符串&#34;。根据{{3}}的建议,另一种方法是使用'\''
,即关闭原始字符串,添加转义'
并打开新字符串。
使用单引号可防止bash将!
解释为历史记录扩展。正如glglgl上面提到的那样另一种选择是使用set +o history
禁用该行为。
作为一个建议,如果你想要捕获正则表达式的不同部分(并且你已经在grep中使用了PCRE模式),你可以改用Perl:
$ perl -lne '/(_t\s*\(\s*(['\''"])(\d+)\2\s*,\s*(['\''"])(.*?)(?<!\\)\4\s*(?(?=,)[^\)]*\s*\)|\)))/ && print "group 1: $1\ngroup 3: $3\n group 5: $5"' file
group 1: _t('123', 'шт.', '', $userLang)
group 3: 123
group 5: шт.
答案 1 :(得分:0)
我强烈建议使用tokenizer extension来解析PHP文件。这是因为解析编程语言需要有状态解析器,单个正则表达式是无状态的,因此无法提供。
以下是一个如何从PHP源文件中提取函数名称的示例,也可以跟踪函数调用:
$source = file_get_contents('some.php');
$tokens = token_get_all($source);
for($i = 0; $i < count($tokens); $i++) {
$token = $tokens[$i];
if(!is_string($token)) {
if($token[0] === T_FUNCTION) {
// skip whitespace between the keyword 'function'
// and the function's name
$i+=2;
// Avoid to print the opening brackets of a closure
if($tokens[$i][0] === T_STRING) {
echo $tokens[$i][1] . PHP_EOL;
}
}
}
}
在评论中你告诉你还要解析html,js文件。我建议使用DOM / JS解析器。