2012-07-16 24 views
6

辞書の単語を含むデータベーステーブルがあります。Mysql繰り返し式のない正規表現の検索

今、アナグラムの単語を選択します。私は、文字列SEPIANを与える場合例えば、それはこのためになどapespainpainspiespinessepia

のような値をフェッチする必要があり、私は、クエリ

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

を使用しかし、このクエリは次のように言葉を返しますannaessenは、指定された文字列にない文字を繰り返しています。例えば。 annaには2つのnがありますが、検索文字列SEPIANには1つだけnがあります。

正規表現を作成するにはどうすればよいですか?また、その時に検索文字列に繰り返し文字がある場合、繰り返し文字は結果に反映されるはずです。

答えて

5

MySQLはキャプチャグループの逆参照をサポートしていないため、(\w).*\1の標準的な解決策は機能しません。つまり、与えられた解はすべての可能な倍を列挙する必要があります。さらに、後方参照がlook-aheadやlook-behindで有効でないことがわかる限り、look-aheadとlook-behindはMySQLではサポートされていません。

ただし、次の2つの式にこれを分割し、次のクエリを使用することができます

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' 

ない非常にきれいなのが、それは動作しますし、それは同様にかなり効率的でなければなりません。


は、繰り返される文字のセットの制限をサポートし、あなたの二次表現のための次のパターンを使用するには:AはあなたのキャラクターとXある

A(.*?A){X,} 

は、それが許可されています回数です。

あなたは(2 N秒の合計)あなたの文字列SEPIANNに別のNを追加しているのであれば、あなたのクエリはなる:

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

を必要としているちょっとそれは私がこれを好きなおかげでたくさん – Nithin

2

私はこのような何かがお手伝いしますね。表words

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

alfagramここでは、アルファベット順に単語の文字です。

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は、あなたが検索したい文字列です。次に、あなたがすべき唯一のことは、クエリを実行している:

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

は、いくつかの追加のチェックと最適化かもしれませ

+0

に動作します。それは賢いです。 – dlras2

+0

賢い考​​えがいいアイデア:-) – Nithin