Mysql正则表达式搜索没有重复的字符

时间:2012-07-16 12:47:07

标签: php mysql regex

我有一个数据库表,其中包含字典中的单词。

现在我想为字谜选择单词。例如,如果我提供字符串SEPIAN,则应该提取apespainpainspiespines,{{1}等值等等。

为此,我使用了查询

sepia

但是这个查询会返回像SELECT * FROM words WHERE word REGEXP '^[SEPIAN]{1,6}$' anna这样的单词,这些单词的重复字符不在提供的字符串中。例如。 essen有两个anna,但搜索字符串n中只有一个n

如何编写正则表达式来实现此目的?此外,如果我的搜索字符串中有重复的字符,那么重复的字符应反映在结果中。

2 个答案:

答案 0 :(得分: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}'

答案 1 :(得分: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.'"');

可能需要进行一些额外的检查和优化