разобрать строку поиска по фразам и ключевым словам - PullRequest
7 голосов
/ 30 октября 2011

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

строка 1: value of "measured response" detect goal "method valuation" study

даст: value,of,measured reponse,detect,goal,method valuation,study

iон также должен работать, если строка имеет:

  1. без фраз, заключенных в кавычки,
  2. любое количество фраз заключено в кавычки с любым количеством ключевых слов вне кавычек
  3. только фразы в кавычках,
  4. только ключевые слова, разделенные пробелом.

Я склоняюсь к использованию preg_match с шаблоном '/(\".*\")/' для перевода фраз вмассив, затем удалите фразы из строки, а затем, наконец, введите ключевые слова в массив.я просто не могу собрать все вместе!

Я также думаю о замене пробелов вне кавычек запятыми.затем взорвать их в массив.Если это лучший вариант, как мне сделать это с preg_replace?

Есть ли лучший способ сделать это?Помогите!всем большое спасибо

Ответы [ 3 ]

10 голосов
/ 30 октября 2011
preg_match_all('/(?<!")\b\w+\b|(?<=")\b[^"]+/', $subject, $result, PREG_PATTERN_ORDER);
for ($i = 0; $i < count($result[0]); $i++) {
    # Matched text = $result[0][$i];
}

Это должно дать результаты, которые вы ищете.

Объяснение:

# (?<!")\b\w+\b|(?<=")\b[^"]+
# 
# Match either the regular expression below (attempting the next alternative only if this one fails) «(?<!")\b\w+\b»
#    Assert that it is impossible to match the regex below with the match ending at this position (negative lookbehind) «(?<!")»
#       Match the character “"” literally «"»
#    Assert position at a word boundary «\b»
#    Match a single character that is a “word character” (letters, digits, etc.) «\w+»
#       Between one and unlimited times, as many times as possible, giving back as needed (greedy) «+»
#    Assert position at a word boundary «\b»
# Or match regular expression number 2 below (the entire match attempt fails if this one fails to match) «(?<=")\b[^"]+»
#    Assert that the regex below can be matched, with the match ending at this position (positive lookbehind) «(?<=")»
#       Match the character “"” literally «"»
#    Assert position at a word boundary «\b»
#    Match any character that is NOT a “"” «[^"]+»
#       Between one and unlimited times, as many times as possible, giving back as needed (greedy) «+»
2 голосов
/ 30 октября 2011
$s = 'value of "measured response" detect goal "method valuation" study';
preg_match_all('~(?|"([^"]+)"|(\S+))~', $s, $matches);
print_r($matches[1]);

выход:

Array
(
    [0] => value
    [1] => of
    [2] => measured response
    [3] => detect
    [4] => goal
    [5] => method valuation
    [6] => study
)

Хитрость здесь в том, чтобы использовать сброс ветви группу: (?|...|...). Это подобно чередованию, содержащемуся в группе без захвата - (?:...|...) - за исключением того, что в каждой ветви номера групп захвата начинаются с того же номера. (Для получения дополнительной информации см. PCRE документы и найдите DUPLICATE SUBPATTERN NUMBERS.)

Таким образом, интересующий нас текст всегда фиксируется группой № 1. Вы можете получить содержимое группы # 1 для всех совпадений с помощью $matches[1]. (Предполагается, что установлен флаг PREG_PATTERN_ORDER; я не указывал его, как @FailedDev, потому что он установлен по умолчанию. Подробнее см. PHP-документы .)

1 голос
/ 08 июня 2015

Нет необходимости использовать регулярное выражение, встроенную функцию str_getcsv можно использовать для разнесения строки с любым заданным разделителем, вложением и escape-символами.

На самом деле это так просто, как

// where $string is the string to parse
$array = str_getcsv($string, ' ', '"'); 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...