preg_match для поиска слов с заглавными буквами и последовательными заглавными словами

Я пытаюсь сопоставить ключевые слова в строках, отфильтровывая только слова, которые соответствуют следующим критериям:

  • слова с заглавными буквами в любом месте, такие как «iPhone» или «CamelCase»
  • последовательные группы слов с большой буквы, такие как «Питтсбург Стилерс» или «Оскар Де Ла Хойя»
  • объединенные выше критерии, такие как «iPhone 5» или «MIB 2» (также рассматривая числа как столицы)
  • сверните любые не символы / цифры, чтобы «О’Доннеллу» было «ODonnells», а «Wi-Fi …» — «Wifi»

Пример:

$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)

Спасибо

2

Решение

Вы можете использовать регулярные выражения, как это:

\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

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

3

Другие решения

Сначала вы можете удалить все не алфавитно-цифровые символы:

$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 заменить любую последовательность пробелов одним пробелом.

3

В добавление к приятному ответу Феде, это будет ваш новый код 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] будет вашим массивом совпадений.

2

Вы можете использовать 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

В дополнение к Феде, Келли и Даниэлю, 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;
}
0
По вопросам рекламы [email protected]