PHP ve düzenli ifadeler: karakteri HTML içeren bir dize tüm karakterleri saymak, ancak sadece 20 görünür kelime ölçüm nasıl?

4 Cevap php

Ben sayfalarından birini kurumsal müşterileri hakkında alıntıyı listeler bir WordPress sitede çalışıyorum.

En görünür metin bu gibi görünüyor nerede bir web sayfası var diyelim:

"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."

Ama bu metinde bir HTML bağlantısı veya görüntü olabilir diyelim, yani ham HTML gibi görünebilir:

"<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."

İşte yapmanız gerekenler: İlk 20 görünür kelimelerin içinde bir bağlantı olup olmadığını öğrenmek.

Bu ilk 20 görünür kelimeler:

"SuperAmazing.com, a subsidiary of Amazing, the leading provider of integrated messaging and collaboration services, today announced the availability of an"

Ben tabii bu sayfadaki her alıntı için farklı olacak olsa da, bu durumda "bir" olacağını 20 görünür kelime, dışarı HTML dahil karakter sayısı, almak gerekir.

(Ben bu şeyleri kolaylaştırır ise 2 kelime olarak "SuperAmazing.com" saymak hazırım.)

Ben kelimeleri sayma için normal ifadelerin dizi çalıştı, ama hepsi HTML değil, görünür kelimeleri saymak.

Peki ilk 20 görünür kelimeleri, HTML gibi, tam karakter sayısını bulmak için doğru düzenli ifade olurdu?

4 Cevap

İşte ilk yirmi görünür eşleşen sözcükleri oldukça iyi bir regex bulunuyor:

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

Bu bir belirteç (bir "kelime" boşluk veya köşeli parantez dışındaki bir veya daha fazla karakter olarak tanımlanabilir nerede) boşlukla ayrılmış değil bir veya daha fazla kelime veya etiketleri gibi tanımlanır bire yirmi boşluk ayrılmış belirteçleri, eşleşir. Örneğin, bu bir simge olacaktır:

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

... Ama bu iki jetonlarını:

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

Bu sayımı kapalı atar ayrı bir belirteci olarak (sizin örnekte <img> etiketi veya boşluklarla çevrili olan herhangi bir etiketi gibi) bağımsız bir etiket tedavi edecek - bu sadece word "olarak kadar maçlar "Sizin örnekte. Onlar don't herhangi bir boşluk varsa, o da doğru, <p> ve <table> gibi <br> etiketleri veya blok düzeyi etiketleri idare olmaz çevrelerindeki. Sadece olacak bir sorunun ne kadar biliyorsunuz.

EDIT: Bu izole <img> etiketi bir çok gördüğünüz bir şey varsa, bunu izleyen boşluk kaldırmak için metni önişlem olabilir. Bu etkin daha doğru bir karakter sayısı ile sonuçlanan, takip eden ilk "gerçek" belirteci ile birleştirmek istiyorum. Ben sadece bu durumda bir veya iki karakter tarafından sayısını değiştirir biliyorum, ama yirminci kelime olduysa "supercalifragilisticexpialidocious" muhtemelen fark ediyorum için. :)

Ben kelimeleri saymak PHP düzenli ifadeler kullanarak hakkında emin değilim.

Eğer bir değişken görünür sözcükleri izole varsayarsak, benim ilk yaklaşım alanlarda (veya kelime olarak görüyorlar ne verir ne olursa olsun) de bölmek ve bir diziye sonuçları koymak / patlayabilir olacaktır.

Bölünmeden sonra, 20 elemanları için dizi sınırlar.

Ardından dizi elemanlarının her biri için normal bir ifade uygulamak ve her maç bir bağlantı olmadığına karar verin.

Karakter sayısını elde etmek için, / join (boşluksuz) yirmi kelimelerin dizi implode ve dizenin uzunluğu bulmak.

Işlevi "getTextFromNode" ve "getTextFromDocument" size HTML salt metin içerik vermek. Işlevi "getFirstWords" metinden kelimelerin ilk sayısını döndürür.

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;
}

Ve bunu tarafından kullanabilirsiniz:

$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";

Umarım bu yardımcı olur.

Regex ve HTML karışmaz. Regex kullanarak sayma sıradışı. Regex sorununuza yanlış bir çözümdür. Metin ayıklamak için bir HTML ayrıştırma kitaplığı kullanın. Sonra kelimeleri ayıklamak için simgeleştiricisine çeşit kullanın. Siz kendinizi uzun vadede baş ağrısı bir çok kazandıracak.

Ne baş ağrısı? Ne istediğinizi yapar canavarca bir regex inşa yönetmek varsayalım. Şimdi iki yıl sonra sizin için hesap vermedi, bir kenar durum var herhalde ve bu ucubeyi değiştirmeniz gerekir. Sen bu noktada size kolayca değiştirebilir kodlu bir çözüm olsaydı olacaktır.