Warning: Cannot use a scalar value as an array in /home/admin/public_html/forum/include/fm.class.php on line 757

Warning: Invalid argument supplied for foreach() in /home/admin/public_html/forum/include/fm.class.php on line 770
Форумы портала PHP.SU :: Версия для печати :: Поиск группы символов в любом порядке без повторов
Форумы портала PHP.SU » PHP » Регулярные выражения » Поиск группы символов в любом порядке без повторов

Страниц (1): [1]
 

1. newcomer - 01 Сентября, 2014 - 21:39:19 - перейти к сообщению
Никак не могу сообразить. Требуется регулярное выражение которое бы находило группу искомых символов в любом порядке в строке любой длины, как это делает выражение /[xyz]{3}/. Проблема в том, что символы не должны повторяться: т.е. может быть так .*(xyz).* или .*(yzx).* или .*(yxz).* . Сама длина группы искомых символов также может варьировать.
2. dcc0 - 02 Сентября, 2014 - 12:09:51 - перейти к сообщению
У вас перестановки. Ради интереса перечитал руководство по preg_match, не нашел встроенного модификатора. Можно считать факториал числа элементов, например из массива и передавать в переменную, только код будет слишком большим.
Интересно, можно ли это сделать с помощью awk из консоли.
3. Мелкий - 02 Сентября, 2014 - 12:40:54 - перейти к сообщению
Ух, это сильное колдунство.

Мой вариант:
PHP:
скопировать код в буфер обмена
  1. $rgAllowedSymbols = array('x','y','z');
  2.  
  3. $sRegexp = '';
  4. $sSymbolmask = '['.preg_quote(join('', $rgAllowedSymbols),'~').']';
  5. for ($iSymbol = 1; $iSymbol < count($rgAllowedSymbols); ++$iSymbol) {
  6.         $sRegexp .= '('.$sSymbolmask . ')' . "(?!".join('|',array_map(function ($el) {
  7.                 return '\\'.$el;
  8.                 }, range(1, $iSymbol))).")";
  9.         }
  10. $sRegexp .= $sSymbolmask;
  11.  
  12.  
  13. var_dump(preg_match_all('~'.$sRegexp.'~', 'foo xyx xyz xxx xyy zyx yxz ff', $rgOut), $rgOut[0]);

Мои ассерты проходит, но по соображениям сопровождаемости делать лучше двупроходным алгоритмом - сперва выбрать [xyz]{3}, потом отфильтровать, например, по count(array_unique(preg_split('~.~', $sMatch))), не равному количеству букв в наборе.
4. dcc0 - 02 Сентября, 2014 - 14:06:48 - перейти к сообщению
Моя мысль была примерно такой. Но на n символов понадобится n циклов и n + неизвестно сколько проверок. Недовольство, огорчение


Спойлер (Отобразить)

(Добавление)
Прав Мелкий, надо сначала получить все размещения, а это есть в preg_match, а потом из них все перестановки.
5. newcomer - 03 Сентября, 2014 - 06:17:57 - перейти к сообщению
Мелкий, спасибо - то, что нужно.
Сам как раз к этому начал подходить, но за основу брал другую регулярку:
CODE (htmlphp):
скопировать код в буфер обмена
  1. "/(?:x()|y()|z()){3}\1\2\3/"

 

Powered by ExBB FM 1.0 RC1