在PHP中使用正则表达式匹配HTML属性

4
我正在尝试制作一个表达式,它可以搜索像how2bypass.co.cc这样的页面,并返回“form”标记中“action”属性以及任何输入标记中“name”和“type”属性的内容。我无法使用html解析器,因为我的最终目标是自动检测给定页面是否为Web代理,一旦网站发现我在做这个,他们可能会做一些傻事,比如用javascript编写整个文档,以防止我解析它。
我正在使用的代码:
    preg_match_all('/<form.*action\="(.*?)".*>[^<]*<input.*type\=/i', $pageContents, $inputMatches);

对于 action 属性,这样做可以正常工作,但是一旦在 type\= 后面加上双引号后,代码就停止工作了。为什么会这样?它只能正常工作一次,但第二次就不行了。

2个回答

1

正则表达式是贪婪的...

如果您检查页面源代码,以下内容可能与第一个<input与最后一个type=匹配,并捕获之间的所有内容。

`<input.*type\=`

你目前的表达式无法捕获表单和所有输入,因为并非每个输入都带有表单标记。您需要采用以下一种方法:

  • 捕获整个表单标记<form>...</form>,然后使用正则表达式匹配捕获中的所有输入
  • 调整当前的表达式为非贪婪模式.*?,并允许多次捕获输入标记。

谢谢,我没想到 .* 会这样做。然而,我的原始问题仍然存在。在表达式中加引号会破坏它,我不明白为什么。为了澄清:为什么 /<form.?action=/i 可以工作,但是 /<form.?action="/i 却没有返回任何东西?如果我无法解决这个问题,我将捕获整个表单标记并逐个处理。另外,我正在测试的页面是我提到的 how2bypass.co.cc。 - some guy

0

在没有看到你想要提取的目标页面的情况下,只有一些猜测:

  • type= 属性可能没有双引号,因为 type=text 也是有效的。或者它可能有单引号,或者在 = 周围有一些空格。
  • 如果标签之间或内部有换行符,则 .* 占位符可能会失败。建议使用 /s 正则表达式标志。
  • 通常更可靠的方法是使用否定字符类,如 [^<>]*[^"],而不是 .*
  • 您不需要转义 \= 等号。

也许你应该把它分开。使用一个正则表达式来提取 <form>..</form> 块。然后在其中搜索 <input> 标签。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接