php的preg_replace模式

时间:2011-07-07 07:12:32

标签: php preg-replace preg-match

我的模式出了点问题。希望有人可以帮助我。

给出一个字符串

$string = Mutualism has been retrospectively characterised as ideologically situated between individualist and collectivist forms of anarchism.<ref>Avrich, Paul. ''Anarchist Voices: An Oral History of Anarchism in America'', Princeton University Press 1996 ISBN 0-691-04494-5, p.6<br />''Blackwell Encyclopaedia of Political Thought'', Blackwell Publishing 1991 ISBN 0-631-17944-5, p. 11.</ref> Proudhon first characterised his goal as a "third form of society, the synthesis of communism and property."<ref>Pierre-Joseph Proudhon. ''What Is Property?'' Princeton, MA: Benjamin R. Tucker, 1876. p. 281.</ref> Another is <ref name=rupert/>

我想删除&lt;ref&gt; (<ref name='something'></ref> or <ref></ref>) or remove the single ref tag <ref name='sss' />

中的字符串 更换最终输出后应该是:

  

互惠主义是追溯性的   在意识形态上表征   位于个人主义者和   集体主义形式的无政府主义。   蒲鲁东首先描绘了他的目标   作为“社会的第三种形式,   共产主义和财产的综合。“   另一个是

我的代码似乎无法正常工作

$pattern1[] = "/&lt;ref[^\/]*\/&gt;/is"; //remove <ref name=something/>  
$pattern1[] = "/&lt;ref[^\/]*&gt;(.*?)&lt;\/ref&gt;/s";  //remove ref <ref>some text here</ref>
preg_replace($pattern1,"\n", $string);

而是输出:

  

互惠主义是追溯性的   在意识形态上表征   位于个人主义者和   集体主义形式的无政府主义。   ''布莱克韦尔政治百科全书   思想'',Blackwell Publishing 1991   国际标准书号0-631-17944-5,p。 11. LT; / REF&GT;   蒲鲁东首先描绘了他的目标   作为“社会的第三种形式,   共产主义和   “另一个是

我想它已经赶上了&lt;br /&gt;

4 个答案:

答案 0 :(得分:1)

不是最有效但非常简单的

$text=strip_tags(str_replace(array('&lt;','&gt;'),array('<','>'),$text));

strip_tags

答案 1 :(得分:0)

问题是你的第一个模式也匹配

  

&lt; ref&gt; Avrich,保罗。 ''无政府主义者   声音:无政府主义的口述历史   在普林斯顿大学的美国   按1996 ISBN 0-691-04494-5,   第6页&lt; br /&gt;

[^\/]*符合以下

  

&gt; Avrich,保罗。 ''无政府主义者的声音:   中国无政府主义的口述史   美国普林斯顿大学出版社   1996年ISBN 0-691-04494-5,第6页&lt; br

解决方案是使用/&lt;ref(?:[^\/&]|&(?!gt;))*\/&gt;/is来匹配标记

在这种情况下,我们使用(?:[^\/&]|&(?!gt;))*代替[^\/]*

第一个(?:[^\/&]|&(?!gt;))*匹配除/和&amp;之外的任何字符,作为第一个选项,或&amp;如果它没有后跟gt;即,不是&gt;的一部分。作为第二个选项的符号(?!gt;)是一个负面的前瞻断言(参见http://www.php.net/manual/en/regexp.reference.assertions.php)这只是意味着不使用gt;,确保接下来的3个字符与此模式不匹配。

第二个只匹配任何不是/.

的字符

所以下面的代码

$str = "Mutualism has been retrospectively characterised as ideologically situated between individualist and collectivist forms of anarchism.&lt;ref&gt;Avrich, Paul. ''Anarchist Voices: An Oral History of Anarchism in America'', Princeton University Press 1996 ISBN 0-691-04494-5, p.6&lt;br /&gt;''Blackwell Encyclopaedia of Political Thought'', Blackwell Publishing 1991 ISBN 0-631-17944-5, p. 11.&lt;/ref&gt; Proudhon first characterised his goal as a &quot;third form of society, the synthesis of communism and property.&quot;&lt;ref&gt;Pierre-Joseph Proudhon. ''What Is Property?'' Princeton, MA: Benjamin R. Tucker, 1876. p. 281.&lt;/ref&gt; Another is &lt;ref name=rupert/&gt;";
$match = array(
    "/&lt;ref(?:[^\/&]|&(?!gt;))*\/&gt;/is",
    "/&lt;ref[^\/]*&gt;(.*?)&lt;\/ref&gt;/s",);
$str = preg_replace($match,'',$str);
echo $str;

输出

  

互惠主义是追溯性的   在意识形态上表征   位于个人主义者和   集体主义形式的无政府主义。   蒲鲁东首先描绘了他的目标   作为“社会的第三种形式,   共产主义和财产的综合。“   另一个是

答案 2 :(得分:0)

我用双引号括起原始字符串:

$string = "Mutualism has been retrospectively characterised as ideologically situated between individualist and collectivist forms of anarchism.&lt;ref&gt;Avrich, Paul. ''Anarchist Voices: An Oral History of Anarchism in America'', Princeton University Press 1996 ISBN 0-691-04494-5, p.6&lt;br /&gt;''Blackwell Encyclopaedia of Political Thought'', Blackwell Publishing 1991 ISBN 0-631-17944-5, p. 11.&lt;/ref&gt; Proudhon first characterised his goal as a &quot;third form of society, the synthesis of communism and property.&quot;&lt;ref&gt;Pierre-Joseph Proudhon. ''What Is Property?'' Princeton, MA: Benjamin R. Tucker, 1876. p. 281.&lt;/ref&gt; Another is &lt;ref name=rupert/&gt;";

$pattern = '#&lt;ref.*?&gt;(.*?&lt;/ref&gt;)?#is';

print htmlspecialchars_decode(preg_replace($pattern, '', $string));
htmlspecialchars_decode转换为双引号需要

&quot - 如果要输出到为您执行此操作的设备(例如浏览器),则省略此项。

输出:

  

互惠主义是追溯性的   在意识形态上表征   位于个人主义者和   集体主义形式的无政府主义。   蒲鲁东首先描绘了他的目标   作为“社会的第三种形式,   共产主义和财产的综合。“   另一个是

备注:

我已将[{1}}换成#,这意味着可以在模式中使用/而无需转义它。

默认情况下,

.*贪婪。在模式中添加?修饰符会使其不合适,这相当于添加U / delimiter

&lt;ref.*?&gt;匹配&lt;ref后跟任何内容,直到找到下一个&gt;

.*?会匹配任何内容,直到下一个&lt;/ref&gt;

.*?&lt;/ref&gt;中包裹()?表示需要找到零次或一次。这适用于有开始和结束标记的情况,以及有开头标记,后面没有内容。

如果您还希望将开头标记与其后面的内容匹配,但没有结束标记,则可以将模式更改为:

$pattern = '#&lt;ref.*?&gt;(.*?&lt;/ref&gt;|.*)#is';

答案 3 :(得分:0)

不建议使用正则表达式解析HTML,但对于这个简单的情况,您可以执行以下操作:

<?php
preg_replace('/<ref.*?\/>|<ref>.*?<\/ref>/', '', $string);