Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/245.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/r/82.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 为什么grep不使用正则表达式?_Php_Regex_Bash - Fatal编程技术网

Php 为什么grep不使用正则表达式?

Php 为什么grep不使用正则表达式?,php,regex,bash,Php,Regex,Bash,我有一个正则表达式来查找文件中的函数 如果我试图从控制台用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 -rP "(_t\s*\(\s*([\'\"])(\d+)\2\s*,\s*([\'\"])(.*?)(?<!\\)\4\s*(?(?=,)[^\)]*\s*\)|\)))" application scripts library public data | sort -n | uniq

grep: unrecognized character after (?<

按照我在评论中所说的做可以解决您的问题(使用链接中的数据):


我强烈建议使用,以便解析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;
            }
        }
    }   
}
$source=file\u get\u contents('some.php');
$tokens=token\u get\u all($source);
对于($i=0;$i

在评论中,您告诉我您还想解析html、js文件。为此,我推荐使用DOM/JS解析器。

这不是一个很好的正则表达式,是吗?正如您所发现的,
字符对双引号内的shell非常重要。就我个人而言,我会用单引号将整个内容括起来,然后对正则表达式中的每个单引号使用
”。无论哪种方式,如果您可以通过向我们展示您试图匹配的模式使您的问题变得独立,这将非常有用。您不需要扩展正则表达式的
-e
标志吗?旁注:您得到的错误不是由
grep
引发的,而是由Bash引发的(查看错误:
-Bash:!\:未找到事件
)。一个简单的修复方法是使用
set+o history
禁用命令历史记录。当我使用exec从PHP运行命令历史记录时,我仍然会在“grep:missing”部分出错。collapsar应该是
-E
(至少在我的grep上是这样),这里OP使用
-P
和启用Perl正则表达式(PCRE)支持“
”\'
。我可能遗漏了什么。。。grep-rP“(\u t\s*([''''''])(\d+)\2\s*,\s*([''''''']])(.*)(?(\grep:后面的字符无法识别)(?@Prosto很抱歉,但这确实超出了原始问题的范围。您的正则表达式现在正在工作,至少在支持PCRE模式的grep版本中是这样。要搜索多个文件,您必须将它们的所有名称传递给Perl。具体如何操作取决于您的shell和最小的目录结构双引号还解释了不匹配的parentesis错误和相关错误;在双引号中,
\\)
减少为
\)
。我解析js和html文件。我也将创建一个示例。但是,如果您也想解析js文件,那么标记器扩展不是这里的选项。我可以用php解析所有文件。这不是问题。问题是性能。Grep的解析速度快了数千倍(我有数千个文件要解析)
$ 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'] . ')
$ 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: шт.
$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;
            }
        }
    }   
}