sınırlı boyutta veritabanı tablosunun içeriği için ayrıştırma metin

2 Cevap php

Ben örneğin bir web sitesinin bir parçası olarak "insan" bir MySQL tablo var:

| people_id  | firstname  | lastname    |
-----------------------------------------
| 1          | John       | Lennon      |
| 2          | Paul       | McCartney   |
| 3          | George     | Harrison    |
| 4          | Ringo      | Starr       |
| .          | .          | .           |

Benim tablo yaklaşık 2000 satır var.

Ben de web sitesinde bir "haber" bölümü var. Sık sık, bu haber örneğin, "insanlar" için başvurular içeren

John Lennon and Paul McCartney wrote some of the most popular songs in the history of rock music.

Mümkün (ya da tavsiye / makul) otomatik olarak veritabanında "insanlar" aramak için haber her bir öğeyi ayrıştırmak, ve sonra bağlantıları bunları açmak için olduğunu. Bu nedenle, örneğin, yukarıda belirtilen bu metin dönüştü (ya da işlevsel olarak eşdeğer bir şekilde) olması:

<a href="/people/1>John Lennon</a> and <a href="/people/2">Paul McCartney</a> wrote some of the most popular songs in the history of rock music.

Bu ne için en iyi yol olacağını? Ben php düzenli ifadeler kullanarak bunu yapmak için birkaç başarısız girişimleri yaptık, ama bu iyi bir yaklaşım değildir sanırım. Javascript (ve çerçeveler) hakkında çok bilinen yok ama bunu yapmak mantıklı eğer bunu kullanmak için mutlu olurdu.

Bu web sitesinin temel bir özellik değil (ama güzel bir ek olacağını hissediyorum) yani ben böyle bir özelliği atlamak için tercih ziyade dramatik sayfa yüklenme süresini arttırmak istiyorum.

EDIT

Ben uzunluğu aşağı tutmak için, ilk soruya bazı detayları atlamış.

Aslında bir futbol kulübü için web sitesi - "halk" tüm web sitesine üye olan ve giriş yapabilirsiniz ve eklemek ve düzenlemek haber (örneğin, maç raporları), sık sık bakın hangi diğer "insanlar". Bu yüzden sadece bana haberleri ekler kim değil - onlar (yaklaşık) 2000, diğer kullanıcılar tarafından eklenebilir.

Üyelik insanlar katılmadan önce onaylanması gerektiğini kısıtlı olmasına rağmen, sistem bu sıradışı isimleri olan insanlar olarak karmaşıklığı ile baş edebilmek için, ve aynı isimde birden fazla kişi birkaç örnekleri vardır.

Ben yukarı / aşağı insanların isimlerini (örn. [p = 1] John Lennon [/ p]) işaretlemek için özel bir kod türünü kullanın ama bir 2000 kullanıcıları, bulduk hangi çözümün bir tür hayata geçirdik Site, bu sadece bir avuç marka kullanım.

Bu değer ne için, web sitesi www.ouafc.com olduğunu ve bir haber bir örnek www.ouafc.com/news/312 yer almaktadır.

2 Cevap

Ben php hakkında çok şey biliyorum, ama burada hızlı bir JavaScript jQuery 1.4 kullanarak ona gitmek, öyle değil mi:

<div id="maindiv">
   John Lennon and Paul McCartney wrote some of the most popular songs in the history of rock music.
</div>


<script>
   $(document).ready(function(){
       myPage.linkify($("#maindiv"));
    })

var myPage = {
    map: {
            "John Lennon": 1,
            "Paul McCartney": 2,
            "Rock Music": 3
         },

    linkify: function(domEl){
        var htmlcopy = domEl.html();

        function buildLink(txt, loc){
            return '<a "href = /blah/'+loc+'>'+txt+'</a>';
        }

        for(i in myPage.map){
           var tmpStr = new RegExp(i,"gi");
           htmlcopy = htmlcopy.replace( tmpStr, buildLink(i, myPage.map[i]) );
       }

       domEl.html(htmlcopy);
    }
 }
</script>

myPage.map veritabanından sunucu tarafında inşa edilecek. Onun bir şey yapmaktan sayfanın kalanını durdurmak olmaz ki bu da (yani harita kapmak olurdu) bir Ajax işlevine geri olabilir.

Yapabileceğiniz en iyi şey elle bir isim göründüğünde göstermek için, bir şekilde haber mesajları işaretlemek için. Bu cevapsız adları, ya da yanlış çözümlü adları önlemek için, ve veritabanından mümkün olan her isim için her haber tarama büyük işleme gereksinimini önlemek için tek yol bu.

Belki twittery-sözdizimi ile gibi bir şey:

@[John Lennon] and @[Paul McCartney] wrote some of the most popular songs in the history of rock music.

Eğer haber görüntülemek istediğinizde sonra özel bir tür markdown-style fonksiyonu ile çalıştırın. Bu, bu belirteçler dışarı ayrıştırmak eşleşen DB kaydı bulmak ve bağlantı oluşturabilir.

Bu veritabanında haber takmadan önce bağlantıları @ [] işaretçileri dönüştürmek için daha verimli olabilir, ama olacağımı daha sıkı çiftler şeyler - Bir kullanıcı silinmiş veya onun kimlik değişikliği, kırık bir bağlantı var ise. Saklanması @ [] Ayrıca düzenleme hikayeler kolaylaştırır.

Update

Eğer isimleri automagically tespit ve bağlantılar dönüştürülür gerekiyorsa, bu isim daha eklemek gibi sadece yetişen oldukça şiddetli performans ceza elde edilebilir:

function linkify_names($news) {
  $people = query('select people_id, firstname, lastname from people');

  $from = $to = array();
  foreach ($people as $person) {
    $name = "$person->firstname $person->lastname";
    // TODO - escape regex chars in $name?

    // match [boundary]$name[boundary], case insensitive
    $from[] = "/(\b)($name)(\b)/i";

    // include boundaries in replacement; maintain case of found name
    $to[] = '$1<a href="/people/' . $person->people_id .'">$2</a>$3';
  }

  return preg_replace($from, $to, $news);
}

Fark yerine @ [] etiketleri ile işaretlenmiş sadece isim ararken, sen all isimleri aramak ve etraflıca her biri için aramak gerekir, olduğunu. Sen haber belgenin gövdesinde adlarını bulmak için basit düzenli ifadeler güvenemez.