Я пытаюсь сопоставить ключевые слова в строках, отфильтровывая только слова, которые соответствуют следующим критериям:
Пример:
$string = "Joe O'Donnell and Oscar De La Hoya went to a Pittsburgh Steelers game on Sunday, where Joe lost his iPhone 5, so he borrowed Oscar's iPad";
preg_match_all("/[A-Z][a-z]*/",$string,$match_words); // incorrect expression
// desired result for $match_words should be:
// array(Joe ODonnell, Oscar De La Hoya, Pittsburgh Steelers, Sunday, Joe, iPhone 5, Oscars, iPad)
Спасибо
Вы можете использовать регулярные выражения, как это:
\b((?:[A-Z]['a-z]*\s*\d*)+)\b|\b((?:[a-z]*[A-Z]['a-z]*\s*\d*)+)\b
Информация о матче:
MATCH 1
1. [0-14] `Joe O'Donnell `
MATCH 2
1. [18-35] `Oscar De La Hoya `
MATCH 3
1. [45-65] `Pittsburgh Steelers `
MATCH 4
1. [73-79] `Sunday`
MATCH 5
1. [87-91] `Joe `
MATCH 6
2. [100-108] `iPhone 5`
MATCH 7
1. [125-133] `Oscar's `
MATCH 8
2. [133-137] `iPad`
Регулярное выражение состоит из двух шаблонов:
\b((?:[A-Z]['a-z]*\s*\d*)+)\b ---> Match words like Joe O'Connels or Oscar De La Hoya
|
\b((?:[a-z]*[A-Z]['a-z]*\s*\d*)+)\b ---> Match words like iPad or iPhone
Кстати, если вы посмотрите на результаты, у них есть завершающий пробел в конце, вы можете сделать обрезку для результата, чтобы очистить его.
Сначала вы можете удалить все не алфавитно-цифровые символы:
$string2 = preg_replace("/[^a-zA-Z0-9\s]/", "", $string);
Тогда используйте preg_split
вместо preg_replace
в Трещина строка последовательностями полностью строчных слов.
$match_words = preg_split("/ ([a-z]| )+ /", $string2);
(Если вы не возражаете, $string
будучи уничтоженным, вы можете заменить $string2
с $string
)
Это работает для примера, который вы предоставили, но подумайте, как ваша программа будет вести себя с менее дезинфицированной информацией. Например, "Foo Bar"
(два пробела) будет разделен на два элемента, тогда как "Foo Bar"
(один пробел) останется как один. Если вы не беспокоитесь о скорости, вы можете использовать другой preg_replace
заменить любую последовательность пробелов одним пробелом.
В добавление к приятному ответу Феде, это будет ваш новый код PHP:
$string = "Joe O'Donnell and Oscar De La Hoya went to a Pittsburgh Steelers game on Sunday, where Joe lost his iPhone 5, so he borrowed Oscar's iPad";
preg_match_all("/\b((?:[A-Z]['a-z]*\s*\d*)+)\b|\b((?:[a-z]*[A-Z]['a-z]*\s*\d*)+)\b/", $string, $matches);
print_r($matches[0]);
$ match [0] будет вашим массивом совпадений.
Вы можете использовать PHP ctype_lower функционировать здесь!
<?php
$string = "Joe O'Donnell and Oscar De La Hoya went to a Pittsburgh Steelers game on Sunday, where Joe lost his iPhone 5, so he borrowed Oscar's iPad";
$words = $temp = array();
// Loop through the string after turning it into an array (by spaces)
foreach (explode(" ", $string) as $word) {
// Check if the word is lowercase and is not a number
if (ctype_lower($word) && !is_numeric($word)) {
if (empty($temp)) continue; // Don't add it if there's nothing to add
// Add the words found up until this point (from the last point) into the words array, as a string
$words[] = implode(" ", $temp);
// Reset the temp array so we can look for new words and continue
$temp = array();
continue;
}
// Add this word to the words array
$temp[] = $word;
}
$words[] = implode(" ", $temp);
// Print the words that have uppercase characters
printf("<pre>%s</pre>", print_r($words, true));
Возвращает:
Array
(
[0] => Joe O'Donnell
[1] => Oscar De La Hoya
[2] => Pittsburgh Steelers
[3] => Sunday,
[4] => Joe
[5] => iPhone 5,
[6] => Oscar's iPad
)
В дополнение к Феде, Келли и Даниэлю, 2 альтернативы для акцентированных языков
С помощью preg_split
$capitalized_words = preg_split("/ ([a-zàèìòùáéíóúýâêîôûãñõäëïöüÿçßøåæœ]| )+ /u", $string);
С помощью preg_match_all
//with 'u' flag
preg_match_all("/\b((?:[A-ZÀÁÂÃÄÅÇÈÉÊËÌÍÎÏÑÒÓÔÕÖØÙÚÛÜÝÆ]['a-zàèìòùáéíóúýâêîôûãñõäëïöüÿçßøåæœ]*\s*\d*)+)\b|\b((?:[a-zàèìòùáéíóúýâêîôûãñõäëïöüÿçßøåæœ]*[A-ZÀÁÂÃÄÅÇÈÉÊËÌÍÎÏÑÒÓÔÕÖØÙÚÛÜÝÆ]['a-zàèìòùáéíóúýâêîôûãñõäëïöüÿçßøåæœ]*\s*\d*)+)\b/u", $string, $capitalized_words);
Использование функции preg_match_all
вместе с trim
function get_capitalized_words($string){
$capitalized_words=array();
//with 'u' flag
preg_match_all("/\b((?:[A-ZÀÁÂÃÄÅÇÈÉÊËÌÍÎÏÑÒÓÔÕÖØÙÚÛÜÝÆ]['a-zàèìòùáéíóúýâêîôûãñõäëïöüÿçßøåæœ]*\s*\d*)+)\b|\b((?:[a-zàèìòùáéíóúýâêîôûãñõäëïöüÿçßøåæœ]*[A-ZÀÁÂÃÄÅÇÈÉÊËÌÍÎÏÑÒÓÔÕÖØÙÚÛÜÝÆ]['a-zàèìòùáéíóúýâêîôûãñõäëïöüÿçßøåæœ]*\s*\d*)+)\b/u", $string, $matches);
if(isset($matches[0])){
$capitalized_words=array_map('trim',$matches[0]);
}
return $capitalized_words;
}