Regex Basics:在两个常量之间抓取文本

时间:2009-02-25 01:09:47

标签: php regex

坚持PHP中的(相当简单的)正则表达式问题。

这一部分埋藏在一堆文字中:

  <tr>
        <td id="descriptionArea">
            Customer request to remove "Intro - 01/13/09" video clip.
            <br/>
        </td>
    </tr>

我想要介于两者之间:

descriptionArea">

...和...

</td>

一位朋友建议:

$pattern = '<td="descriptionArea">\s*(.*?)\s*<';
$clean = preg_replace("'[\n\r\s\t]'","",$text); // to rid of line breaks
preg_match($pattern, $clean, $matches);
print_r($matches);

但是我收到以下错误:

Warning: preg_match() [function.preg-match]: Unknown modifier 'q'

我想第二个问题是preg_match是否也是正确的PHP函数。我应该使用ereg吗?谢谢你的帮助。

6 个答案:

答案 0 :(得分:4)

使用preg_*函数时,第一个字符或模式被视为分隔符:

  

表达式必须包含在分隔符中,例如正斜杠(/)。任何字符都可以用于分隔符,只要它不是字母数字或反斜杠(\)。如果必须在表达式本身中使用分隔符,则需要使用反斜杠进行转义。从PHP 4.0.4开始,您还可以使用Perl风格的(){}[]<>匹配分隔符。
   - Regular Expressions (Perl-Compatible) – Introduction

所以你不需要像其他人所说的那样逃避或替换&个字符。而是使用适当的分隔符并在表达式中转义这些字符:

'/&lt;td id=&quot;descriptionArea&quot;&gt;(.*?)&lt;\/td&gt;/'

答案 1 :(得分:2)

你想要逃脱“&amp;”,就像wombleton所说的那样,并且还用正斜线包围你的模式,比如$ pattern =“/ pattern /”;

下面的代码返回一个包含一些丑陋内容的数组,但至少它返回一个匹配.. :)

$description = " &lt;tr&gt;
        &lt;td id=&quot;descriptionArea&quot;&gt;
            Customer request to remove &quot;Intro - 01/13/09&quot; video clip.
            &lt;br/&gt;
        &lt;/td&gt;
    &lt;/tr&gt;";

$pattern = "/&lt;td.*[&]quot;descriptionArea[&]quot;[&]gt;\s*(.*?)\s*.*?lt/";
$clean = preg_replace("'[\n\r\s\t]'","",$description); // to rid of line breaks

preg_match($pattern, $clean, $matches);
var_dump($matches);

修改

这是一个更好的版本。摆脱所有HTML编码,以便您可以使用标准的HTML解析正则表达式:

$pattern = '/<.*?id="descriptionArea">(.*?)<\/td>/';
$clean = preg_replace("'[\n\r\t]'","",htmlspecialchars_decode($description)); 
preg_match($pattern, $clean, $matches);

答案 2 :(得分:1)

我怀疑它将&符号解释为某种控制字符。但是我找不到支持这个的参考。

尝试用&替换[&]的所有实例。

答案 3 :(得分:1)

如果你想在两个常量之间抓取文本,那么使用好的'strpos'不是更容易吗?

修改

e.g。

$string = 'text to be >searched< within';
$const1 = '>';
$const2 = '<';
$start = strpos($string, $const1);
$end = strpos($string, $const2, $start + strlen($const1));
$result = substr($string, $start, $end - $start);

我没有运行它,所以它可能是错误的,但你应该明白这一点。

答案 4 :(得分:0)

你在$ pattern中使用了以下内容?

$pattern = '(?s:descriptionArea&quot;&gt;(.*)&lt;/td&gt;)';

我不懂PHP,但是当我测试它时,RegEx似乎在正则表达式设计器中工作。 (?s :)的选项是'Singleline On'。

标记

答案 5 :(得分:0)

您获得的具体错误来自preg_ *函数,使用模式的第一个字符作为分隔符(在本例中为“&amp;”),以及第二次出现作为修饰符的分隔符后的所有内容(例如“i” “用于不区分大小写。”

在这种情况下,它认为您正在寻找lt;td=,并且您想要修饰符quot;descriptionArea&quot;&gt;\s*(.*?)\s*&lt;。第一个修饰符“q”没有意义,它就会失败。