Как найти пересечения слов в строках и объединить в группы похожие строки (php)?
Примерно так: https://ideone.com/kylhD6
Конечно, надо немного доработать, чтобы определяло именно слова, а не совпадения по буквам. То есть сейчас он в Ленинград и "Ленинградский" запихнет. upd:
https://ideone.com/aBSGzA
Допилил так, чтобы искал именно слова, а не просто вхождения строки.
Если нужно искать именно слова, то можно допилить так:strpos(" ".$phrase." ", " ".$word." ") !== false
Исходный код:spoiler<?php
$arr = [
'Концерт группы Ленинград',
'Группа ZebraHead',
'ZebraHead',
'Группа СПЛИН',
'Ленинград',
'Концерт группы ZebraHead',
'ZebraHead. Презентация альбома',
'СПЛИН в Олимпийском',
'Крематорий',
'Группировка Ленинград'
];
$newarr = [];
 
$words = [];
$result = [];
 
foreach($arr as $key => $val){
    //приводим к нижнему регистру
    $val = strtolower($val);
 
    //убираем знаки препинания и прочие символы
    $val = str_replace(".", "", $val);
    $val = str_replace(",", "", $val);
    $val = str_replace("/", "", $val);
    $val = str_replace(";", "", $val);
    $val = trim($val);
 
    //запоминаем "очищенные" слова
    $newarr[$key] = $val;
 
    //разделяем слова в массив
    $cw = explode(" ", $val);
 
    //запоминаем весь список слов
    foreach($cw as $word){
    	array_push($words, $word);
    }
}
 
 
foreach($words as $word){
	$ca = [];
 
	foreach($newarr as $key => $phrase){
		//проверяем, что фраза содержит это слово
		if(strpos($phrase, $word) !== false){
			//если так, то запоминаем
			array_push($ca, $arr[$key]);
		}
	}
 
	$result[$word] = $ca;
}
 
print_r($result);
Без ошибок и без словаря, в котором будут выставлены веса для отдельных слов - никак.
Поясню. У вас стоит задача разбить строки с упором на музыкальные группы (отталкиваюсь от вашего примера), значит для всех названий групп должен стоять приоритет группировки, иначе объединение будет происходить случайным образом - по первым попавшимся словам.