2012-07-16 8 views
6

Tengo una tabla de base de datos con palabras de un diccionario.Búsqueda de expresión regular de Mysql sin caracteres repetitivos

Ahora quiero seleccionar palabras para un anagrama. Por ejemplo, si le doy la cadena SEPIAN se debe descargar valores como apes, pain, pains, pies, pines, sepia, etc.

Para ello he utilizado la consulta

SELECT * FROM words WHERE word REGEXP '^[SEPIAN]{1,6}$' 

Pero esta consulta devuelve palabras como anna, essen que tienen caracteres repetidos que no están en la cadena suministrada. P.ej. anna tiene dos n, pero solo hay uno n en la cadena de búsqueda SEPIAN.

¿Cómo puedo escribir mi expresión regular para lograr esto? Además, si hay caracteres repetidos en mi cadena de búsqueda en ese momento, los caracteres repetidos deben reflejarse en el resultado.

Respuesta

5

Dado que MySQL no es compatible con los grupos de captura de referencia, la solución típica de (\w).*\1 no funcionará. Esto significa que cualquier solución dada deberá enumerar todos los dobles posibles. Además, por lo que puedo decir, las referencias no son válidas en look-aheads o look-behinds, y look-aheads y look-behinds no son compatibles con MySQL.

Sin embargo, puede dividirla en dos expresiones, y utilizar la siguiente consulta:

SELECT * FROM words 
WHERE word REGEXP '^[SEPIAN]{1,6}$' 
AND NOT word REGEXP 'S.*?S|E.*?E|P.*?P|I.*?I|A.*?A|N.*?N' 
No

muy bonito, pero funciona y que debe ser bastante eficiente.


para apoyar un límite conjunto de caracteres repetidos, utilice el siguiente patrón para su expresión secundaria:

A(.*?A){X,} 

Dónde A es su carácter y X es el número de veces que está permitido.

Así que si va a añadir otra N a la cadena de SEPIANN (para un total de 2 N s), su consulta se convertiría en:

SELECT * FROM words 
WHERE word REGEXP '^[SEPIAN]{1,7}$' 
AND NOT word REGEXP 'S.*?S|E.*?E|P.*?P|I.*?I|A.*?A|N(.*?N){2}' 
+0

oye, funciona gracias mucho – Nithin

2

supongo que algo como esto le ayudará. Tabla words:

| id | word  | alfagram | 
--------------------------------- 
| 1  | karabar | aaabkrr | 
| 2  | malabar | aaablmr | 
| 3  | trantantan| aaannnrttt| 

alfagram aquí es letras de una palabra en un orden alfabético.

código PHP:

$searchString = 'abrakadabra'; 
$searchStringAlfa = array(); 
for($i=0,$c=strlen($searchString);$i<$c;$i++){ 
    if(isset($searchStringAlfa[$searchString[$i]])){ 
     $searchStringAlfa[$searchString[$i]]++; 
    }else{ 
     $searchStringAlfa[$searchString[$i]] = 1; 
    } 
} 
ksort($searchStringAlfa); 
$regexp = '^'; 
foreach($searchStringAlfa as $alfa=>$amount){ 
    $regexp .= '['.$alfa.']{0,'.$amount.'}'; 
} 
$regexp .= '$'; 

$searchString es la cadena que desee buscar con.Entonces lo único que debe hacer es ejecutar la consulta:

$result = mysql_query('SELECT * FROM words WHERE alfagram REGEXP "'.$regexp.'"'); 

puede haber algunas comprobaciones adicionales y se necesitan optimizaciones

+0

me gusta esto. Es inteligente. – dlras2

+0

pensamiento inteligente buena idea :-) – Nithin

Cuestiones relacionadas