我正在使用WordPress网站,其中一个网页列出了有关公司客户的摘录。
假设我有一个网页,其中可见文字如下所示:
"SuperAmazing.com, a subsidiary of Amazing, the leading provider of
integrated messaging and collaboration services, today announced the
availability of an enhanced version of its Enterprise Messaging
Service (CMS) 2.0, a lower cost webmail alternative to other business
email solutions such as Microsoft Exchange, GroupWise and LotusNotes
offerings."
但是,假设此文本中可能有HTML链接或图像,因此原始HTML可能如下所示:
<img src="/images/corporate/logos/super_amazing.jpg" alt="Company
logo for SuperAmazing.com" /> SuperAmazing.com, a subsidiary of
<a href="http://www.amazing.com/">Amazing</a>, the leading
provider of integrated messaging and collaboration services, today
announced the availability of an enhanced version of its Enterprise
Messaging Service (CMS) 2.0, a lower cost webmail alternative to other
business email solutions such as Microsoft Exchange, GroupWise and
LotusNotes offerings."
这是我需要做的:找出前20个可见单词中是否有链接。
这是前20个可见单词:
"SuperAmazing.com, a subsidiary of Amazing, the leading provider of
integrated messaging and collaboration services, today announced the
availability of an"
我需要将字符数(包括HTML)输出到20个可见单词,在这种情况下它将是“an”,但当然它对于页面上的每个摘录都会有所不同。
(如果这样可以让事情变得简单,我愿意将“SuperAmazing.com”视为2个单词。)
我尝试了一些用于计算单词的正则表达式,但它们都计算HTML,而不是可见单词。
那么,对于前20个可见单词,查找完整字符数(包括HTML)的正确正则表达式是什么?
答案 0 :(得分:2)
我不确定使用PHP正则表达式计算单词。
假设你可以隔离变量中的可见单词,我最初的方法是在空格处爆炸/拆分它(或任何给出你认为是单词的东西)并将结果放入数组中。
拆分后,将数组限制为20个元素。
然后将正则表达式应用于每个数组元素,并确定是否匹配链接。
要获取字符数,请加入/内嵌20个单词的数组(不含空格)并找到字符串的长度。
答案 1 :(得分:2)
函数“getTextFromNode”和“getTextFromDocument”为您提供HTML的纯文本内容。函数“getFirstWords”返回文本中的第一个单词数。
function getTextFromNode($Node, $Text = "") {
if ($Node->tagName == null)
return $Text.$Node->textContent;
$Node = $Node->firstChild;
if ($Node != null)
$Text = getTextFromNode($Node, $Text);
while($Node->nextSibling != null) {
$Text = getTextFromNode($Node->nextSibling, $Text);
$Node = $Node->nextSibling;
}
return $Text;
}
function getTextFromDocument($DOMDoc) {
return getTextFromNode($DOMDoc->documentElement);
}
function getFirstWords($Text, $Count = 1) {
if (!($Count > 0))
$Count = 1;
$Text = trim($Text);
$TextParts = split('[ ]+', $Text, 21);
if (count($TextParts) == $Count)
$TextParts[$Count - 1] = "";
$NewText = join(" ", $TextParts);
return $NewText;
}
你可以通过以下方式使用它:
$Doc = new DOMDocument();
$Doc->loadHTMLFile("Test.html");
$Text = getTextFromDocument($Doc);
echo "Text from HTML: ".$Text."\n";
$NewText = getFirstWords($Text, 21);
echo "First 20 words from HTML: ".$NewText."\n";
希望这有帮助。
答案 2 :(得分:2)
这是匹配前20个可见单词的相当不错的正则表达式:
'~^(?:\s*+(?:(?:[^<>\s]++|</?\w[^<>]*+>)++)){1,20}~'
这匹配一到二十个以空格分隔的标记,其中标记被定义为一个或多个不用空格分隔的单词或标签(其中“单词”被定义为除空格或尖括号以外的一个或多个字符)。例如,这将是一个标记:
<a href="http://www.amazing.com/">Amazing</a>
...但这是两个令牌:
<a href="http://www.superduper.com/">Super Duper</a>
这会将独立标记(例如示例中的<img>
标记或任何被空格包围的标记)视为单独的标记,从而丢弃计数 - 它只匹配单词“ “在你的例子中。它还无法正确处理<br>
标记或<p>
和<table>
等块级标记,如果它们不周围有任何空格。只有你能知道会有多少问题。
编辑:如果您看到很多孤立的<img>
标记,您可以预处理文本以删除其后面的空格。这将有效地将其与第一个后续“真实”令牌合并,从而产生更准确的字符数。我知道在这种情况下它只会将计数改为一个或两个字符,但如果第二十个字发生在“supercalifragilisticexpialidocious”中,你可能会注意到它的区别。 :)
答案 3 :(得分:1)
正则表达式和HTML不混合。使用正则表达式计数是不寻常的。正则表达式是您的问题的错误解决方案。使用HTML解析库来提取文本。然后使用某种形式的tokenizer来提取单词。从长远来看,你会为自己省去很多麻烦。
有什么头疼的?假设你设法构建一个可以满足你想要的怪异正则表达式。现在假设两年后有一个你没有考虑的边缘情况,你需要修改那个怪物。您将在那时希望您有一个可以轻松修改的编码解决方案。