2012-07-16 96 views
6

我有一個數據庫表中有字典中的單詞。Mysql正則表達式搜索沒有重複字符

現在我想選擇一個字謎的單詞。例如,如果我給串SEPIAN應該像apespainpainspiespinessepia取值等

爲此,我使用的查詢

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

但這個查詢返回類的字眼anna,essen重複字符不在提供的字符串中。例如。 anna有兩個n's,但在搜索字符串SEPIAN中只有一個n

如何寫我的正則表達式來實現這一點?此外,如果當時我的搜索字符串中有重複的字符,重複的字符應反映在結果中。

回答

5

由於MySQL不支持反向引用捕獲組,所以(\w).*\1的典型解決方案將不起作用。這意味着任何解決方案都需要枚舉所有可能的雙打。此外,據我所知,反向引用在預見或後視中無效,並且MySQL中不支持預視和後視。

但是,您可以拆分到這兩個表達式,並使用下面的查詢:

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(.*?A){X,} 

哪裏A是你的性格和X是它允許的次數。

因此,如果您要添加另一個N到您的字符串SEPIANN(共2個N S),您的查詢就會變成:

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 2012-07-17 05:27:26

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 2012-07-16 15:32:02

+0

聰明的想法好主意:-) – Nithin 2012-07-17 05:27:49