Поиск по маске

Mich

Продвинутый новичёк
Поиск по маске

Подскажите, как реализовать поск по маске. Например, маска: ???aaa???. Совпдает: ajseeeajs, ksbuuusbe, pxfwwwsdf и т.д.

Заранее спасибо.
 

Mich

Продвинутый новичёк
любое_количество_любых_символов три_одинаковых_символа любое_количество_любых_символов
 

white phoenix

Новичок
PHP:
function mask2pattern($mask)
{
 $mask = strtolower($mask);
 $u = '';
 for($i=0;$i<strlen($mask);$i++)
 {
  $char = $mask{$i};
  $part = '';
  $f = FALSE;
  if (($p = strpos($u,$char)) !== FALSE) {$f = TRUE; $part = '\\'.($p+1);}
  elseif ($char == '?') {$part = '.';}
  elseif ($char == '*') {$part = '.*';}
  else {$f = TRUE; $part = '(.)'; $u .= $char;}
  if ($f)
  {
   $h = array();
   for($j=0;$j<strlen($u);$j++) {if ($u{$j} != $char) {$h[] = '\\'.($j+1);}}
   if (count($h) > 0) {$part = '(?!'.implode('|',$h).')'.$part;}   
  }
  $pattern .= $part;
 }
 return '~^'.$pattern.'$~';
}
$string = 'pxfABCCXYYZdgf';
$mask = '???abccxyyz???';
$pattern = mask2pattern($mask);
var_dump($pattern);
$result = preg_match($pattern,$string) > 0;
var_dump($result);
// bool(true)
$result примет TRUE в случае совпадения, FALSE в случае несовпадения.

UPD: Доделал чтобы маска 'abc' в строке '111' давала FALSE.
 

Mich

Продвинутый новичёк
Спасибо большое. А вот это как.: ?abc. Совпадет: qxyz, r123, t678 и т.д. На словах, хотя бы.
 

white phoenix

Новичок
> А вот это как.: ?abc. Совпадет: qxyz, r123, t678 и т.д. На словах, хотя бы.
О чем ты?
 

Mich

Продвинутый новичёк
abc, 123 - по порядку идущие символы. Алгоритм вроде такой же, пробую сделать. Спасибо.

-~{}~ 12.02.06 00:47:

Не-а. Не получается составить рег. Подскажите, как будет выглядеть рег, который находит в тексте по порядку стоящие буквы/цифры. Есть текст: "qweabcdseixyz". Рег должен вернуть: "abc" и "xyz". Это можно сделать в одном?
 

Mich

Продвинутый новичёк
Должен. Просто не заметил. Я же не рег =)
> А зачем это делать рег. выражением?
Я же спросил - можно? Если нет - то вроде и незачем :)
 

white phoenix

Новичок
baev
Должен.
Mich
Можно, но не нужно.
PHP:
$string = 'qweabcdseixyz';
$found = array();
for($i=0;$i<strlen($string);$i++) {$found[] = $string{$i};}
natsort($found);
$sorted = join('',$found);
$found = array();
for($i=0;$i<=strlen($sorted)-3;$i++)
{
 $sub = substr($sorted,$i,3);
 if (strpos($string,$sub) !== FALSE) {$found[] = $sub;}
}
$found = array_unique($found);
var_dump($found);
/*
array(3) {
  [0]=>
  string(3) "abc"
  [1]=>
  string(3) "bcd"
  [2]=>
  string(3) "xyz"
}
*/
Видел исправленный код выше? То что нужно?
 

baev

‹°°¬•
Команда форума
white phoenix

мда...
Не, я понимаю — Вы свой код точно проверяли.
Ага. Именно в том виде, как сюда запостили.

Ну и, в принципе, он полностью решает конкретную задачу...
...с конкретной строкой.

А попробуйте-ка строчку заменить на:
PHP:
$string = 'weabcdseiqxyz';
— заметьте, я только одну букву на другое место передвинул...

P.S. Вообще, зачем все эти манипуляции с исходной строкой?
Не проще было сравнение проводить со строкой из всех букв/цифр в «естественном порядке»?
 

Mich

Продвинутый новичёк
baev
если строка длинная, то да, если нет - так быстрее.
 

Mich

Продвинутый новичёк
Да.
ЗЫ В дальнейшем такие вопросы можно пропускать, я думаю.
 

white phoenix

Новичок
Mich
Можешь и пропускать :)
С натуральной сортировкой мой пример делает немного не то. Он ищет тройки символов идущие в "естественном" порядке. Сейчас допишу... там с дистанцией делается.
 
Сверху