#php #regex #parsing
#php #регулярное выражение #синтаксический анализ
Вопрос:
Приведенный ниже код принимает ключевое слово и строку текста (очищенную от html-тегов) и определяет, появляется ли ключевое слово в последнем предложении очищенного содержимого.
Есть один сбой, который я не могу понять. Когда в конце содержимого содержится хотя бы пустое пространство или тег абзаца с неразрывным пробелом, т.Е.
This is the last sentence.<p>amp;nbsp;</p>
Я получаю ложноотрицательное значение (нет совпадения), несмотря на то, что (1) Ключевое слово определенно присутствует в последнем предложении и (2) функция strip_tags () должна обеспечить отсутствие проблемы с появлением тега в конце.
Кто-нибудь понимает, почему это может происходить?
function plugin_get_kw_last_sentence($post) {
$theContent = strip_tags(strtolower($post->post_content));
$theKeyword = 'test';
$thePiecesByKeyword = plugin_get_chunk_keyword($theKeyword,$theContent);
if (count($thePiecesByKeyword)>0) {
$theCount = $thePiecesByKeyword[count($thePiecesByKeyword)-1];
$theCount = trim($theCount,'.');
if (substr_count($theCount,'.')>0) {
return FALSE;
} else {
return TRUE;
}
}
return FALSE;
}
function plugin_get_chunk_keyword($theKeyword, $theContent) {
if (!plugin_get_kw_in_content($theKeyword,$theContent)) {
return array();
}
$myPieceReturn = preg_split('/b' . $theKeyword . 'b/i', $theContent);
return $myPieceReturn;
}
Комментарии:
1. Вам нужно дважды перерезать границы этих слов, \ b
2. @Tony, спасибо. Можете ли вы помочь мне понять, почему?
3. в PHP обратная косая черта используется для экранирования символов в строках, заключенных в кавычки. Итак, чтобы в вашем регулярном выражении была буквальная обратная косая черта, вам нужно экранировать ее другой обратной косой чертой.
4. Спасибо, Тони, я ценю ваше объяснение и ваше элегантное решение вопроса.
Ответ №1:
У вас там происходит много такого, что, я думаю, может быть описано только в регулярном выражении, если я правильно понимаю вашу логику. Нельзя ли свести всю логику к этому:
function plugin_get_kw_last_sentence($post) {
$pattern = '/' . $theKeyword . '[^.!?]*[.!?][^.!?]*$/';
$subject = strip_tags(strtolower($post->post_content));
return preg_match($pattern, $subject);
}
Регулярное выражение совпадает, когда оно находит ваше ключевое слово и знак препинания в конце последнего предложения, между которыми нет других знаков препинания в конце предложения.
Теперь это, очевидно, не является пуленепробиваемым, поскольку такие вещи, как заголовки (например, Mr., Mrs.) и т.д. … и все остальное, включая эти знаки препинания в конце предложения, сбивают вас с толку. Это должно дать вам то, что вы просите, поскольку ваш приведенный код также не учитывает эти ситуации.
Комментарии:
1. @Tony, звучит логично. Сейчас запускаю его через несколько тестов. Я полагаю, я мог бы разработать обходной путь для наиболее распространенных исключений, которые вы упоминаете. На самом деле, это была бы неплохая идея. Спасибо за помощь.
2. @Tony, я пытаюсь протестировать, но получаю: Предупреждение: preg_match() [function.preg-match]: Неизвестный модификатор ‘*’ (в строке preg_match()). ?
3. добавьте косые черты, чтобы открывать и закрывать шаблон регулярных выражений, который я вам дал. Проверьте мою правку в коде выше. Извините за это.
4. Это исправило сообщение об ошибке. Спасибо. Проблема в том, что ваша функция, как и моя, все еще возвращает ЛОЖНЫЕ отрицания. Мое ключевое слово — «ключевое слово test» в последнем предложении, которое звучит так: «Ключевое слово test находится здесь. <p>amp;nbsp;</p>»
5. …Однако, когда я меняю предложение на: «Ключевое слово test находится здесь». Я получаю return TRUE, как и ожидал.