regex — PHP разбивает строку на известные токены, а оставшиеся слова добавляют в массив из одного слова

В поисках умного, очень легкого и творческого способа преобразования строки заголовка в токенизированный объект, но с учетом не разбиваемых заранее известных двухсловных предопределенных словарных слов.

т.е .:
словарь содержит более 300 слов / наборов слов, таких как:
простыня, куртка, костюм, оксфордские туфли

Строка может содержать что-то вроде:
4-х частей 1000TC 100% хлопок королева простыня в цвет слоновой кости

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

поэтому сначала я делаю регулярные выражения и удаляю все, что не является a-zA-Z, по крайней мере, {2,} char long

тогда я хочу получить следующий массив:

  • хлопок
  • Королева
  • набор листов
  • цвета слоновой кости

где набор листов останется в виде одного токена, поскольку он содержится в нашем словаре.

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

-1

Решение

Давайте предположим, что ваш словарь хранится в простом массиве.
Тогда пригодится регулярное выражение:

<?php

$dictionary = array('sheet set', 'jacket', 'suit', 'oxford shoes');
$regexp = implode('|', $dictionary);
$regexp .= '|[a-z]{2,}';
$regexp = '/(?<=[^\w-]|^)('.$regexp.')(?=[^\w-]|$)/i';
// final regexp looks like this:
// /(?<=[^\w-]|^)(sheet set|jacket|suit|oxford shoes|[a-z]{2,})(?=[^\w-]|$)/i

$subject = '4-Piece 1000TC 100% Cotton Queen Sheet Set in Ivory';

preg_match_all($regexp, $subject, $matches);

Совпадения (полный шаблон, первый индекс таблицы соответствий):

array(5) {
[0]=>
string(6) "Cotton"[1]=>
string(5) "Queen"[2]=>
string(9) "Sheet Set"[3]=>
string(2) "in"[4]=>
string(5) "Ivory"}

PS ‘in’ соответствует шаблону, потому что есть минимум 2 символа, вы можете настроить его на 3, чтобы получить желаемый результат.

Краткое объяснение:

  • i модификатор гарантирует, что строка соответствует регистронезависимому
  • (?<=[^\w-]|^) а также (?=[^\w-]|$) площадь lookarounds это не гарантирует ничего интересного за пределами искомого слова

И тест производительности: http://3v4l.org/siK9h/perf#tabs

1

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

Если вам нужно что-то очень быстрое, вы можете подумать о построении древовидной структуры из своего словаря (каждый символ будет связан со следующим), тогда в каждом месте вы должны попытаться спуститься по дереву.

Вы можете посмотреть на http://en.wikipedia.org/wiki/Trie

Однако, если скорость является основной проблемой, вы должны избегать php.

1

По вопросам рекламы [email protected]