разбор текста для содержимого таблицы базы данных ограниченного размера - PullRequest
4 голосов
/ 03 февраля 2010

У меня есть MySQL таблица "people" как часть веб-сайта, например:

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

В моей таблице около 2000 строк.

У меня также есть раздел "новости" на веб-сайте. Часто эти новости содержат ссылки на «людей», например,

Джон Леннон и Пол Маккартни написали некоторые из самых популярных песен в история рок-музыки.

Возможно ли (или разумно / целесообразно) автоматически проанализировать каждый элемент новостей, чтобы найти «людей» в базе данных, а затем превратить их в ссылки. Так, например, приведенный выше текст будет преобразован в это (или что-то функционально эквивалентное):

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

Каков наилучший способ сделать это? Я сделал несколько неудачных попыток сделать это с помощью регулярных выражений в php, но я думаю, что это не лучший подход. Я не знаю много о javascript (и его фреймворках), но я был бы рад использовать это, если это имеет смысл.

Это не является существенной функцией веб-сайта (но я считаю, что это было бы хорошим дополнением), поэтому я предпочел бы опустить такую ​​функцию, а не резко увеличивать время загрузки страницы.

EDIT

Я пропустил некоторые детали в первоначальном вопросе, чтобы уменьшить длину.

Фактически это веб-сайт футбольного клуба - все «люди» являются членами веб-сайта и могут входить в систему, добавлять и редактировать новости (например, отчеты о матчах), на которых они часто ссылаются на других "людей". Так что не только я добавляю новости - их могут добавлять (около) 2000 других пользователей.

Хотя членство ограничено в том смысле, что люди должны быть одобрены до присоединения, система должна быть в состоянии справиться со сложностями, такими как люди с необычными именами, и есть несколько случаев, когда более одного человека с одним именем .

Я реализовал своего рода решение, в котором я использую собственный код для разметки имен людей (например, [p = 1] Джон Леннон [/ p]), но я обнаружил, что в 2000 году пользователи сайта, только немногие используют это.

Что бы это ни стоило, веб-сайт www.ouafc.com, а пример новостной ленты - www.ouafc.com/news/312.

.

Ответы [ 2 ]

2 голосов
/ 03 февраля 2010

Я не очень разбираюсь в php, но вот быстрый пример использования JavaScript с использованием jQuery 1.4:

<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 будет построен на стороне сервера из базы данных. Это также может быть обратным вызовом функции Ajax (которая будет захватывать карту), чтобы не мешать остальной части страницы делать свое дело.

1 голос
/ 03 февраля 2010

Лучше всего вручную каким-либо образом пометить новостные сообщения, чтобы указать, когда появляется имя.Это единственный способ предотвратить пропущенные имена или неправильно проанализированные имена, а также избежать огромных требований к обработке сканирования каждой новости для каждого возможного имени из базы данных.

Может быть что-то с твиттер-синтаксисом вроде:

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

Затем запустите его с помощью пользовательской функции markdown в стиле, когда вы хотите отобразить новость.Он может разобрать эти маркеры, найти соответствующую запись в БД и сгенерировать ссылку.

Было бы более эффективно преобразовывать маркеры @ [] в ссылки перед вставкой новости в базу данных, но это объединяетвещи более плотно - если пользователь удален или его идентификатор меняется, у вас битая ссылка.Хранение @ [] также облегчает редактирование историй.

Обновление

Если вам необходимо автоматически определять имена и преобразовывать их в ссылки, это может быть достигнуто при довольно серьезном снижении производительности, которое только увеличиваетсякогда вы добавляете больше имен:

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

Разница в том, что вместо поиска только имен, помеченных тегами @ [], вы должны искать всех имен и вести тщательный поисккаждый.Вы не можете полагаться на простые регулярные выражения для поиска имен в теле новостного документа.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...