2

私は、ページの1つに企業クライアントに関する抜粋がリストされているWordPressサイトで作業しています。

表示されるテキストが次のようになっているWebページがあるとします。

"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を含む完全な文字数を見つけるための正しい正規表現は何でしょうか。

4

4 に答える 4

2

PHPの正規表現を使用して単語を数えるかどうかはわかりません。

変数内の表示されている単語を分離できると仮定すると、私の最初のアプローチは、スペース(または単語と見なすもの)でそれを分解/分割し、結果を配列に入れることです。

分割後、配列を20要素に制限します。

次に、各配列要素に正規表現を適用し、リンクに一致するものがあるかどうかを判断します。

文字数を取得するには、20語の配列(スペースなし)を結合/内包し、文字列の長さを見つけます。

于 2009-09-04T01:22:45.390 に答える
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";

お役に立てれば。

于 2009-09-04T02:47:55.593 に答える
2

最初の20個の表示された単語を一致させるための適度に良い正規表現は次のとおりです。

'~^(?:\s*+(?:(?:[^<>\s]++|</?\w[^<>]*+>)++)){1,20}~'

これは、1〜20個の空白で区切られたトークンに一致します。トークンは、空白で区切られていない1つ以上の単語またはタグとして定義されます(「単語」は、空白または山括弧以外の1つ以上の文字として定義されます)。たとえば、これは1つのトークンになります。

<a href="http://www.amazing.com/">Amazing</a>

...しかし、これは2つのトークンです。

<a href="http://www.superduper.com/">Super Duper</a>

<img>これにより、スタンドアロンタグ(例のタグや空白で囲まれたタグなど)が個別のトークンとして扱われ、カウントが失われます。例の「of」という単語にのみ一致します。また<br>、タグ、またはやのようなブロックレベルのタグは<p>、周囲に空白がない<table>場合は正しく処理されません。あなただけがどれだけの問題になるかを知ることができます。

編集:その孤立した<img>タグがよく見られるものである場合は、テキストを前処理して、それに続く空白を削除することができます。これにより、最初の後続の「実際の」トークンと効果的にマージされ、より正確な文字数が得られます。この場合、カウントが1〜2文字しか変更されないことはわかっていますが、20番目の単語が「supercalifragilisticexpialidocious」になっている場合は、おそらく違いに気付くでしょう。:)

于 2009-09-04T03:05:30.220 に答える
1

正規表現とHTMLは混在しません。正規表現を使用してカウントするのは珍しいことです。正規表現はあなたの問題に対する間違った解決策です。HTML解析ライブラリを使用してテキストを抽出します。次に、何らかの形式のトークナイザーを使用して単語を抽出します。長期的には、多くの頭痛の種を減らすことができます。

どんな頭痛がしますか?あなたがあなたが望むことをする巨大な正規表現を構築することに成功したとしましょう。ここで、2年後に、説明しなかったエッジケースがあり、その怪物を変更する必要があるとします。その時点で、簡単に変更できるコード化されたソリューションがあればいいのにと思います。

于 2009-09-04T01:44:06.330 に答える