我正在尝试查找具有某些不同特征的歌曲名称。这些是条件:
我将Musicbrainz数据作为postgres数据库,其中包含可查询的大量歌曲。我试图以几种方式查询数据,但没有得到想要的结果。
例如,下面的代码示例:
$strings = [
'12895 6 7 8 9',
'2546734 34 55',
'2334734556 341 5',
];
function formatNumber($number)
{
preg_match('/(\d+) ?((?:[\d]\s*){4})$/', $number, $matches);
if (!$matches) {
return $number;
}
return sprintf('%s %s', $matches[1], str_replace(' ', '', $matches[2]));
}
var_dump(array_map('formatNumber', $strings));
会让我半途而废,但这并不尊重我正在寻找的事实:
上面的查询(我知道这是错误的)会产生以下结果:
array(3) {
[0] =>
string(10) "12895 6789"
[1] =>
string(12) "2546734 3455"
[2] =>
string(15) "2334734556 3415"
}
select name from track where name ilike 'b% a% s% h%'
第一个是错误的,因为Brothers in Arms
不满足第二个单词必须以“ A”开头并且总共必须包含4个单词的要求。
第二个单词是错误的,因为它不能满足总共需要四个单词的要求,即使前三个单词很匹配。
任何指针都值得赞赏!
答案 0 :(得分:1)
您可以查看regular expressions。假设单词边界只能是一个空格(对于歌曲名称来说似乎是合理的),您可以尝试:
...
WHERE name ~* '^b[^ ]* a[^ ]* s[^ ]* h[^ ]*$'
...
第一个^
匹配字符串的开头,$
匹配字符串的结尾。 [^ ]
是一个字符类,表示除空格以外的任何字符-^
实际上是“否定”该类,或更准确地说,是其补语。也就是说,它匹配该类的任何字符。 *
是一个量词,表示该类可以定义任意数量的字符,包括零。
如果存在多个空格字符,而不是多个空格序列的空格本身,请尝试:
...
WHERE name ~* '^b\S*\s+a\S*\s+s\S*\s+h\S*$'
...
\S
和\s
还是字符类,但是是预定义的字符类。 \S
表示任何字符,除非它是空白字符,而\s
则是任何空白字符。