2012-07-16 108 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