Регулярное выражение для сопоставления от первого верхнего регистра до конца предложения строки, чтобы выделить массив слов - PullRequest
1 голос
/ 21 декабря 2011

Я знаю, что название довольно сложно понять. В основном я получил текст, скажем, около 20000 символов.

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

Я получил массив выделенных слов, который называется $ words, и позвольте назвать основной текст $ text. Итак, мой код следующий:

foreach($words as $word):

    $regex = '/[^.!?\n]*\b'.preg_quote($word,"/").'\b[^.!?\n]*/i';

    preg_match_all($regex, $text, $matches);  
    count($matches[0]) > 3 ? $search_q= 3 : $search_q=count($matches[0]);

    for ($i=0; $i < $search_q; $i++):
        echo preg_replace('/\b('.preg_quote($word,"/").')\b/i','<span class="highlighted">$1</span>',$matches[0][$i]).'[..]  ';
    endfor;
endforeach;

Проблема с этим кодом состоит в том, что когда 2 слова принадлежат одному и тому же предложению, предложение будет напечатано дважды. Я хочу напечатать его только один раз, выделив оба слова, но я не знаю, как это сделать.

Спасибо за помощь, ребята

ОБНОВЛЕНИЕ: СЦЕНАРИЙ ТЕСТА

Предположим, что:

$text="A new holiday shopping tradition: Smartphones and social networks

Many consumers will take out their phones before their wallets this holiday season with even more visiting social media sites before tackling their gift lists.

More than one-quarter (27 percent) of smartphone owners plan to use their devices for holiday shopping to search for store locations (67 percent), compare prices (59 percent) and check product availability (46 percent).  Additionally, 44 percent say they plan to use social media to seek discounts, read reviews and check family and friends’ gift lists.

“Consumers are using online and mobile platforms to make the most of their holiday budgets, and the survey indicates that they will do more than just compare prices,” said Paul.  “Retailers that use mobile and online channels to show product availability, locations and pricing but add customized promotions and gift ideas may encourage shoppers to come in the door for a specific gift and take additional items to the register.”";

И слова такие:

$words=array('social','media');

С моим кодом я получаю это:

A new holiday shopping tradition: Smartphones and **social** networks[..]
Many consumers will take out their phones before their wallets this holiday season with even more visiting **social** media sites before tackling their gift lists[..]
Additionally, 44 percent say they plan to use **social** media to seek discounts, read reviews and check family and friends’ gift lists[..]
Many consumers will take out their phones before their wallets this holiday season with even more visiting social **media** sites before tackling their gift lists[..]
Additionally, 44 percent say they plan to use social **media** to seek discounts, read reviews and check family and friends’ gift lists[..]

Вместо этого я хочу:

A new holiday shopping tradition: Smartphones and **social** networks[..]
Many consumers will take out their phones before their wallets this holiday season with even more visiting **social** **media** sites before tackling their gift lists[..]
Additionally, 44 percent say they plan to use **social** **media** to seek discounts, read reviews and check family and friends’ gift lists[..]

С кодом FGE я получаю:

social[..] 
social[..] 
social[..] 
media[..] 
media[..] 

Я надеюсь, что с примерами это легко понять. Большое спасибо

Ответы [ 2 ]

1 голос
/ 21 декабря 2011

Ваша голова, вероятно, будет болеть меньше, если вы разделите текст на массив предложений и изучите каждое предложение по очереди. Если список слов не слишком длинный, вы можете поместить весь список в свое регулярное выражение. Что-то вроде:

/\b(\Qword1\E|\Qword2\E|\Qword3\E)\b/
0 голосов
/ 21 декабря 2011

Во-первых, я не понимаю, почему вы используете такое сложное регулярное выражение: вы действительно используете привязки слов, так зачем беспокоиться о дополненных классах символов?

Во-вторых, это решение предполагает, что слова не содержат специальных символов регулярных выражений ...

Вот что вы можете сделать:

$w = preg_quote($word, "/");
$fullword = '\b\Q' . $w . '\E\b';
$regex = '/' . $fullword . '(?!.*' . $fullword . ')/i';

Объяснение: \Q означает, что все символы, вплоть до \E, , должны обрабатываться буквально (что означает, что вы в безопасности, если слово содержит точку). Итак, вы соответствуете своему слову (оно привязано), и затем вы говорите, что не должны соответствовать слову снова (?!.*\b\Qwordhere\E\b).

Это означает, что если предложение содержит слово несколько раз, оно будет соответствовать только последнему вхождению!

Наконец, чтобы выделить, используйте:

preg_replace('/(' . $fullword . ')/ig', '<span class="highlighted">$1</span>', $text);
...