【问题标题】:How to find a js object in a string?如何在字符串中找到一个js对象?
【发布时间】:2017-07-22 17:31:18
【问题描述】:

我正在尝试编写一个正则表达式来在字符串中查找一个 js 对象。

$test = "var contactData = {
    'address': '',
    'email': '',
    'phone': '09121269001',
    'fax': ''
};";

preg_match_all('/^contactData\s[=:]\s{(.*)};$/m', $test, $matches, PREG_PATTERN_ORDER);
var_dump($matches);

这是我得到的结果。

array (size=2)
  0 => 
    array (size=0)
      empty
  1 => 
    array (size=0)
      empty

【问题讨论】:

  • 你想得到什么?为什么不 json_decode()?
  • 在要求基于正则表达式的解决方案时,最好提供 2 或 3 个不同的示例字符串,以便提供最佳解决方案。如果所有字符串都严格/可靠地采用这种格式,那么正则表达式不是最好的方法。请在您的问题中包含您希望输入样本的确切输出。

标签: php json regex preg-match-all


【解决方案1】:

如果正则表达式是您想要的,那么我认为这是一个很好的解决方案。

http://www.phpliveregex.com/p/kOh

preg_match_all("/'(.*?)'/", $test, $Matches);

从图片中可以看出,$match[0][1] 是地址,[2][3] 电子邮件等等。


如果您希望每个组作为一个新变量,您可以使用以下代码来创建变量,而不是使用数组。
$test = "var contactData = {
    'address': 'foobar',
    'email': 'fofo@foo.com',
    'phone': '09121269001',
    'fax': '1234'
};";


preg_match_all("/'(.*?)'/", $test, $Matches);

foreach($Matches[1] as $val){
    $$val = next($Matches[1]);
}

echo $address . "\n" . $email ."\n" . $phone ."\n". $fax;

输出:

foobar
fofo@foo.com
09121269001
1234

https://3v4l.org/CMvYB

【讨论】:

    【解决方案2】:

    m 修饰符使锚点(^$)一次匹配 1 行。您的第一行也以var 开头,因此您不能使用前导锚,或者您需要添加它。您可以将s 修饰符与上述任何一种方法一起使用,这将起作用。

    /contactData\s[=:]\s\{(.*)\};$/s
    

    /^var contactData\s[=:]\s\{(.*)\};$/s
    

    演示:https://regex101.com/r/xCE6UD/2/https://regex101.com/r/xCE6UD/1/

    您还应该转义{}s。使用 .* 作为贪婪,您将匹配到字符串中的最后一个 },如果您有多个 JSON 字符串,这将是不正确的。另一种方法也可以是:

    contactData\s[=:]\s\{([^}]+)};$
    

    https://regex101.com/r/xCE6UD/3/

    【讨论】:

      【解决方案3】:

      这将是正则表达式:

      /\'(.*)\'\: \'(.*)\'/
      

      此处发布的概念证明: https://xrg.es/#12zb4f1

      preg_match_all("/\'(.*)\'\: \'(.*)\'/", "$test", $matches, null, 0);
      

      所以$matches[1][2] = 到phone 所以$matches[2][2] = 到09121269001

      【讨论】:

      • 这个答案在模式中的单引号和冒号上有不必要的转义——不应该教。无需双引号 $testpreg_match_all() 中的第 4 和第 5 个参数无需声明。您还可以考虑使用否定字符类 [^'] 而不是点,因为它会更有效。每当提交基于正则表达式的 SO 解决方案时,请尽最大努力提供最准确、最有效和最简短的模式。这样未来的 SO 读者将学习最佳实践。
      • 您在上面演示您的模式的站点并不好,因为它显示了一个冗长的 php 表达式——正如我在之前的评论中提到的那样。此外,它不会告诉您模式中所需的“步骤”。我建议在regex101.com 上进行测试和演示,因为它告诉您您的模式的效率。了解这些步骤可以帮助您改进模式以提高效率。您还可以比较其他答案的步数,看看您的比较。作为一种自我教育工具,这将非常有用..
      【解决方案4】:

      json_decode() 专门用于执行此任务时,禁止使用正则表达式解析 json 对象。它只要求您在解码之前准备好字符串。 json_decode() 做了所有必要的工作来准备一个易于访问的关联数组。

      下面的 sn-p 将首先为您提供最终结果,然后 Tarantino 它为您提供导致它的所有步骤。

      代码:(Demo)

      $test = "var contactData = {
          'address': '',
          'email': '',
          'phone': '09121269001',
          'fax': ''
      };";
      // step #4 / final output -> use json_decode to generate associative array:
      var_export(json_decode(rtrim(strstr(str_replace("'",'"',$test),'{'),';'),true));
      
      echo "\n\n";
      // step #1 -> swap single quotes for double quotes:
      var_export(str_replace("'",'"',$test));
      echo "\n";
      // step #2 -> extract json object start to end of string:
      var_export(strstr(str_replace("'",'"',$test),'{'));
      echo "\n";
      // step #3 -> trim trailing semi-colon from substring (several funcs can do this part)
      var_export(rtrim(strstr(str_replace("'",'"',$test),'{'),';'));
      

      输出:

      array (
        'address' => '',
        'email' => '',
        'phone' => '09121269001',
        'fax' => '',
      )
      
      'var contactData = {
          "address": "",
          "email": "",
          "phone": "09121269001",
          "fax": ""
      };'
      '{
          "address": "",
          "email": "",
          "phone": "09121269001",
          "fax": ""
      };'
      '{
          "address": "",
          "email": "",
          "phone": "09121269001",
          "fax": ""
      }'
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-11-08
        • 2011-01-16
        • 1970-01-01
        • 2013-03-31
        • 1970-01-01
        相关资源
        最近更新 更多