正则表达式,匹配字符串之间的字符串,然后匹配该匹配项中的字符串

时间:2013-04-28 15:27:52

标签: php regex

我想在该结构中解析uploadify方法的选项:

<script>
$(function() {
  $("#file_upload_1").uploadify({
    uploader : '/uploadify/uploadify.php',
  });
});
</script>

我可以使用以下方法在脚本标记之间提取所有内容:

$matches = array(); reg_match('/.*<script>(.*)<script>/s', $s, $matches);

但不知道如何进一步前进。我需要在“uploadify({”(因为它是关键字)之前删除$ matches [1]中的所有内容,并在首次出现“})之后删除”;

3 个答案:

答案 0 :(得分:0)

你的模式中似乎没有丢失斜线:

/.*<script>(.*)<\/script>/s

更改分隔符会更容易:

~.*<script>(.*)</script>~s

请注意,这将为您提供输入中的最后一个<script>对(.*将尽可能多地消耗,尽可能地推送两个标记)。如果这就是你想要的,那么公平。

在任何情况下,最好使用DOM解析器获取script标记的内容。它更健壮,更具可读性和诸如此类的东西。 Here is an overview of your options to do that using PHP.

现在提出你的实际问题。同样,JavaScript或JSON解析器可能有所帮助,但使用正则表达式,您可以使用non-greedy重复,以确保您的匹配仅上升到第一个});

/uplodify[(][{](.*?)[}][)];/s

这种方法的主要问题是});可能出现在字符串或注释中,或者甚至可能是嵌套匿名函数的结尾。虽然PCRE在正则表达式中提供了递归(?R)构造,但是尝试使用它来解析JavaScript必然会使你的大脑(以及任何试图在将来理解代码的人)大脑融化。这就是为什么(对于一个强大的解决方案),这应该使用某种JavaScript解析器来解决。

你甚至可能会更好,只是寻找uploadify,然后逐个字符地浏览其余的字符串,计算JavaScript的不同嵌套级别,以确保你正在寻找适用于});

答案 1 :(得分:0)

你似乎在你的正则表达式函数中错过了p,因为php提供了preg_match。尽管如此,您可以使用以下正则表达式来匹配uploadify方法;

preg_match('/<script>.*?(uploadify\({.*?}\);).*<\/script>/s', $s, $matches);

答案 2 :(得分:0)

因为你真的想要选项,一个JS对象,这里是一个死星大小的矫枉过正解决方案来解析这些东西。这里的想法是提取你想要的部分,放在JS中的{} JSON对象之间,然后使用PHP的 json_decode 将其评估为可用的结构。在这段代码中,我将HTML片段存储到$ variable0中。

// expression broken down for readability
$frag = array(
    "/<script>",
    ".*?",             # whitespace
    "uploadify\(",
        "(.*?)",       # our desired match
    "\);",             # closest )
    "(.*)",            # more whitespace we don't want
    "<\/script>/s"
);

// flatten expression into match string
$expr = implode("", $frag );

所以在这一点上,$ expr是/<script>.*?uploadify\((.*?)\);(.*)<\/script>/s

$m = preg_match( $expr, $variable0, $r );

现在$ r应该是一个数组,其中$ r [1]包含“{...}”代码段。这可以使用 json_decode 进行评估,但是,对于要使用的json_decode,字符串格式错误。首先,密钥必须用javascript中的引号括起来(即:uploader:''应该是'uploader':'')。从字面上看,$ r [1]看起来像这样:

{
    uploader : '/uploadify/uploadify.php',
  }

另一个人提出了我们可以在这里申请的清洁功能。

// fix thanks to http://stackoverflow.com/a/14075951/415324
function fix_json( $a ) {
    $a = preg_replace('/(,|\{)[ \t\n]*(\w+)[ ]*:[ ]*/','$1"$2":',$a);
    $a = preg_replace(
      '/":\'?([^\[\]\{\}]*?)\'?[ \n\t]*(,"|\}$|\]$|\}\]|\]\}|\}|\])/','":"$1"$2',
    $a);

    return( $a );
}

// $r[1] will contain innards of uploadify(), which is JSON
$json = fix_json( $r[1] );

这会将$ json变成PHP可以本地解析的东西。 $ json现在看起来像:

{"uploader":"/uploadify/uploadify.php',"}

请注意,那里有一个尾随的逗号。这是您正在提取的原始HTML中的javascript错误,需要在网站上修复。更多关于以下内容。

$options = json_decode( $json );

此时,我们有一个可以在PHP中使用的对象

var_dump( $options );

object(stdClass)#2 (1) {
  ["uploader"]=>
  string(24) "/uploadify/uploadify.php"
}

因此,您可以使用echo $options->uploader;

轻松访问遇到的任何其他选项

注意:原始HTML存在问题 - 它包含一个在某些浏览器中破解javascript解析的尾随逗号。想想FireFox会减少一些松懈,但肯定不是IE。要修复JS,请删除选项对象中的尾随逗号:

$("#file_upload_1").uploadify({
  uploader : '/uploadify/uploadify.php'
});