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

7

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

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

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

Мне также нужно, чтобы он работал, если строка имеет:

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

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

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

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

Теги:
string
parsing

3 ответа

10
Лучший ответ
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) «+»
  • 0
    Вау. будет работать над этим сейчас, defs даст вам знать как можно скорее, как только я получу это работает.
  • 0
    Эпический Скажи, что! спасибо @FailedDev
Показать ещё 14 комментариев
2
$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
)

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

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

  • 0
    Не могли бы вы опубликовать тест Perl, где работает это регулярное выражение? Или это поддерживается только в php? Мне бы хотелось, чтобы это работало, но я не могу заставить его работать с моим инструментом.
  • 0
    Удивительно, Алан, снова узнал что-то новое. тем не менее, что делать, если я хочу игнорировать общие слова из тех, которые не заключены в кавычки? как 'Array ([1] => Array ([1] => of))'? скажем, у меня есть массив запрещенных слов, таких как array ('at','the','and','of','in') , как мне включить это в подход? большое спасибо!
Показать ещё 3 комментария
1

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

Действительно, это так же просто.

// where $string is the string to parse
$array = str_getcsv($string, ' ', '"'); 

Ещё вопросы

Сообщество Overcoder
Наверх
Меню