【问题标题】:How to resolve unexpected token error with grep, regex, and PHP?如何使用 grep、regex 和 PHP 解决意外的令牌错误?
【发布时间】:2024-01-14 16:46:01
【问题描述】:

我对 REGEX 非常了解,但我一直坚持这一点。我正在使用 PHP 5.4 到 shell_exec() 一个带有 REGEX 的 grep 语句,以捕获文本文件中的 SKU。在 php 中我没有看到错误,但 grep 不起作用。

目标是在此文本中捕获 SKU:

{'Product_Product_SKU':               'DOP36M94DPM'},

PHP 代码:

$cmdSKU1 = 'grep -Po \'(?<=\{\'Product_Product_SKU\':\s{15}\').+?(?=\'\}\,)\' '.$FileName;
$chkSKU1 = trim(shell_exec($cmdSKU1));

此外,当我在我使用的 IDE 的调试器工具中查看 $cmdSKU1 变量时,它的值是一行:

grep -Po '(?<=\{'Product_Product_SKU':\s{15}').+?(?='\}\,)' /opt/web/default/RetailerParsing/RetailerDownload/MDD30TMSTH__20220113091043.htm

此外,当我将它粘贴到 Ubuntu 控制台时,它给了我错误:

-bash: syntax eror near unexpected token `)'

即使我回去转义暴露的单引号。事实上,我逃脱了所有 [^A-Za-z0-9] 只是为了确保!没有豆子。

最后,如果我尝试在 PHP IDE 中对 REGEX 中的单引号进行双重转义,我会在 Produce_Product_SKU 字下看到一个红色波浪下划线错误。

【问题讨论】:

    标签: php regex bash grep token


    【解决方案1】:

    您没有正确转义 shell 命令。与其手动操作,不如使用​escapeshellarg

    $cmdSKU1 = join(" ", array_map( 'escapeshellarg', array(
       ​"grep",
       ​"-Po",
       ​"(?<={'Product_Product_SKU':\s{15}').+?(?='},)",
       ​$FileName
    )));
    $chkSKU1 = trim(shell_exec($cmdSKU1));
    

    也就是说,为什么不直接使用 preg_match 并保存对非 POSIX 外部命令的调用?

    $string = "{'Product_Product_SKU':               'DOP36M94DPM'},";
    
    preg_match("/{'Product_Product_SKU':\s{15}'([^']+)'}/", $string, $matches);
    
    var_dump($matches[1]);
    string(11) "DOP36M94DPM"
    

    当然,你必须阅读 php 中的文件,但它可能值得额外的代码。

    【讨论】:

    • 这就是票!谢谢,弗拉瓦多纳。我很欣赏清晰而有见地的答案 - 而且速度很快。学到了一些对我非常有用的东西,我可以将其纳入我的网络抓取工作中。我们的规范是多次使用 grep 文件提取价格等。使用“读取文件然后 preg_match”方法可能会占用较少的资源。我应该调查的东西。非常感谢。
    【解决方案2】:

    这里根本不需要正则表达式,当然也不需要 shell_exec。只需拆分 ' 并从结果数组中取出第 4 个(0 索引)值:

    $str = "{'Product_Product_SKU':               'DOP36M94DPM'},";
    $sku = explode("'", $str)[3];
    var_dump($sku);
    

    产量:

    string(11) "DOP36M94DPM"
    

    另请注意,PHP 5.4 已于 6 年前终止。你真的应该更新。

    【讨论】:

    • 根据我对问题的理解,模式是从文件中提取的
    • 模式?不,该模式显然是硬编码的。我认为您的意思是 要搜索的文本 来自文件。在不知道该文件中还有什么内容的情况下,很难提供比仅将示例字符串转储到变量中的更多详细信息。
    • 感谢 Alex,但我正在阅读大量文本文件以搜索 SKU。不过,请欣赏它。