我使用regexp来根据需要转换文本,但我想保留HTML标记。
例如如果我想用“堆栈下溢”替换“堆栈溢出”,这应该工作
预期:如果输入为stack <sometag>overflow</sometag>
,我必须获得stack <sometag>underflow</sometag>
(即字符串替换已完成,但是
标签还在那里......
答案 0 :(得分:9)
在处理操作HTML时使用DOM库,而不是正则表达式:
http://blog.ianbicking.org/2008/03/30/python-html-parser-performance/被盗。
其中我会推荐lxml,html5lib和BeautifulSoup。
答案 1 :(得分:3)
Beautiful Soup或HTMLParser是您的答案。
答案 2 :(得分:3)
请注意,无法明确地进行任意替换。请考虑以下示例:
HTML:
A<tag>B</tag>
模式 - &gt;替换:
AB -> AXB
可能的结果:
AX<tag>B</tag>
A<tag>XB</tag>
HTML:
A<tag>A</tag>A
模式 - &gt;替换:
A+ -> WXYZ
可能的结果:
W<tag />XYZ
W<tag>X</tag>YZ
W<tag>XY</tag>Z
W<tag>XYZ</tag>
WX<tag />YZ
WX<tag>Y</tag>Z
WX<tag>YZ</tag>
WXY<tag />Z
WXY<tag>Z</tag>
WXYZ
哪种算法适用于您的案例在很大程度上取决于可能的搜索模式的性质以及处理歧义的所需规则。
答案 3 :(得分:1)
使用lxml
或BeautifulSoup
提供的html解析器。另一种选择是使用XSLT转换(XSLT in Jython)。
答案 4 :(得分:0)
我认为到目前为止发布的DOM / HTML解析器库建议并未解决给定示例中的特定问题:overflow
仅在underflow
之前应替换为stack
在渲染文档中,它们之间是否有标记。但是,这样的库是解决方案的必要部分。
假设标签永远不会出现在单词的中间,那么一个解决方案就是
1. HTML DOM,
stack <sometag>overflow</sometag>
成为DOM
#1;stack <sometag>#2;overflow</sometag>
和2.明文生成:
#1;stack #2;overflow
3.中所需的正则表达式是#(\d+);stack\s+#(\d+);overflow\b
和替换#\1;stack %\2;underflow
。请注意,只有第二个单词通过在唯一标识符中将#
更改为%
来标记,因为第一个单词不会被更改。
在4.中,从生成的纯文本中提取带有唯一标识符underflow
的单词2
,因为通过将#
更改为%
来标记
在5.中,所有#(\d+);
标识符都从DOM的文本节点中删除,同时在提取的单词中查找它们的数字。找不到号码1
,因此#1;stack
仅替换为stack
。找到更改后的单词2
的数字underflow
,因此#2;overflow
会被underflow
取代。
最后在6.中,DOM被渲染回HTML文档`stack underflow。
答案 5 :(得分:-1)
尝试有趣的东西。它有点有效。当我将这个脚本附加到textarea并让他们“翻译”东西时,我的朋友喜欢它。我想你可以用它做任何事情。咩。如果您打算使用它,请检查几次代码,它可以工作,但我对这一切都是新手。我认为自从我开始学习php之后已经有两三个星期了。
<?php
$html = ('<div style="border: groove 2px;"><p>Dear so and so, after reviewing your application I. . .</p><p>More of the same...</p><p>sincerely,</p><p>Important Dude</p></div>');
$oldWords = array('important', 'sincerely');
$newWords = array('arrogant', 'ya sure');
// function for oldWords
function regex_oldWords_word_list(&$item1, $key)
{
$item1 = "/>([^<>]+)?\b$item1(tionally|istic|tion|ance|ence|less|ally|able|ness|ing|ity|ful|ant|est|ist|ic|al|ed|er|et|ly|y|s|d|'s|'d|'ve|'ll)?\b([^<>]+)?/";
}
// function for newWords
function format_newWords_results(&$item1, $key)
{
$item1 = ">$1<span style=\"color: red;\"><em> $item1$2</em></span>$3";
}
// apply regex to oldWords
array_walk($oldWords, 'regex_oldWords_word_list');
// apply formatting to newWords
array_walk($newWords, 'format_newWords_results');
//HTML is not always as perfect as we want it
$poo = array('/ /', '/>([a-zA-Z\']+)/', '/’/', '/;([a-zA-Z\']+)/', '/"([a-zA-Z\']+)/', '/([a-zA-Z\']+)</', '/\.\.+/', '/\. \.+/');
$unpoo = array(' ', '> $1', '\'', '; $1', '" $1', '$1 <', '. crap taco.', '. crap taco with cheese.');
//and maybe things will go back to normal sort of
$repoo = array('/> /', '/; /', '/" /', '/ </');
$muck = array('> ', ';', '"',' <');
//before
echo ($html);
//I don't know what was happening on the free host but I had to keep stripping slashes
//This is where the work is done anyway.
$html = stripslashes(preg_replace($repoo , $muck , (ucwords(preg_replace($oldWords , $newWords , (preg_replace($poo , $unpoo , (stripslashes(strtolower(stripslashes($html)))))))))));
//after
echo ('<hr/> ' . $html);
//now if only there were a way to keep it out of the area between
//<style>here</style> and <script>here</script> and tell it that english isn't math.
?>