Как я могу выделить два слова вокруг строки внутри строки, но не перекрывать предложения? - PullRequest
1 голос
/ 21 февраля 2012

Мне нужно выделить слово для поиска и его контекст (в предложении).

Рассмотрим строку:

Lorem Ipsum Dolor Sit Amet. Consuteteer adipiscing elit.

Если поисковый термин Lorem ipsum, то результат должен быть:

Lorem ipsum dolor sit амет. Consuteteer adipiscing elit.

Если поиск dolor sit, результат должен быть:

Lorem ipsum dolor sit amet. Concetetuer adipiscing elit.

Если поиск Consectetuer, результат должен быть:

Lorem ipsum dolor sit amet. Секретарь, отвечающий за элиту.

Как вы рекомендуете делать это (в php)?

Выделение поискового термина достаточно просто:

$string = str_replace($query,'<strong>' . $query . '</strong>', $string);

Но как я могу включить два слова до и после, не перекрывая следующее или предыдущее предложение?

Ответы [ 2 ]

5 голосов
/ 21 февраля 2012

Вы можете разбить строку на «предложения» (разделить на точку (как насчет восклицательных знаков, вопросительных знаков, ...)).

Затем найдите предложение с соответствующим словом.

Затем разбейте это предложение на «слова» и добавьте несколько тегов в два слова до и после соответствующего слова. Поскольку у вас есть только одно предложение для работы, вы должны включить проверку, чтобы убедиться, что вы не вышли за пределы массива слов.

Затем соедините слова вместе и соедините все предложения вместе.


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

$string = preg_replace("/\\b(\\w+ +){0,2}$query( +\\w+){0,2}\\b/i",
                       '<strong>$0</strong>',
                       $string);

Регулярное выражение работает следующим образом (обратные слэши экранируются выше):

\b        | match a word boundary (ie match whole words)
(\w+ +)   | match a "word" followed by spaces (to separate it from the next word)
{0,2}     | match 0 to 2 of these such words (it will match as many as possible
          | up to 2)
$query    | match the '$query' string
( +\w+)   | regex for space (separating $query) followed by a word
{0,2}     | match 0 to 2 of these words (as many as possible up to 2)
\b        | match a word boundary (ie match whole words)

/i в конце означает «без учета регистра».

Строка замены <strong>$0</strong> означает замену всеми подобранными словами, заключенными в теги 'strong'.

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

Есть обычные предостережения (которые вы применили бы к любому методу, который использовали) - хотите, чтобы жирный шрифт проходил через вопросительные знаки? восклицательные знаки? Допускается ли апостроф одним словом? Что вы будете делать с пунктуацией без остановок между словами? и т.д.

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

  • разрешить апострофы в слове: измените \w+ на [\w']+ (не используйте обратную косую черту для PHP)
  • разрешить различные знаки препинания между словами: заменить + на что-то вроде [\s\-&,]+ (означает, что между словами допускаются "пробел", "-", "&", "," - добавьте больше по своему вкусу, но не ставьте «.», чтобы жирный шрифт не проходил через полные остановки).
1 голос
/ 21 февраля 2012

Надеюсь, это поможет

$str ="your whole string ";
if(isset($_POST['searchStr']))
{
$searchStr= $_POST['searchStr'];
$str= str_replace($searchStr,'<b>'. $searchStr.'</b>',$str);
}
echo "$str";

если вы хотите замену без учета регистра, используйте функцию ниже

    str_ireplace() - Case-insensitive version of str_replace.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...