У меня есть несколько сломанных заголовков, где каждая буква всегда разделена одним пробелом или более. Слова в этих заголовках разделены на большее количество пробелов, чем каждая буква, но количество пробелов варьируется.
Вот несколько примеров названий (знак минус обозначает пробел).
"H-E-L-L-O--W-O-R-L-D"
"H--E--L--L--O----W--O--R--L--D"
"H--E--L-L--O---W--O--R--L--D----A-N-D----G-O-O--D-B--Y-E"
"Y--O--U----A--R--E----W-O-N--D-E-R-F-U--L"
Я хочу исправить эти заголовки, но все мои решения до сих пор были слишком сложными. Такое ощущение, что это должно быть простой проблемой.
Какие-либо решения?
РЕДАКТИРОВАТЬ: Это решение, которое я выбрал в конце, который основан на среднем,
function filterSpacesBetweenLetters($str)
{
if (preg_match_all('/ +/', $str, $matches)) {
$lengthValues = array_map('strlen', $matches[0]);
$countValues = array_count_values($lengthValues);
$average = array_sum(array_keys($countValues)) / count($countValues);
$minLength = ceil($average);
$words = preg_split('/ {' . $minLength . ',}/', $str);
$words = array_map(function ($str) {
return str_replace(' ', '', $str);
}, $words);
return implode(' ', $words);
}
return $str;
}
Все, что я могу придумать, — это иметь механизм, который ищет наибольшее количество символов тире в последовательности и применять правила замены в наборах 3/4 или 1/2.
$text = <<<END
H-E-L-L-O--W-O-R-L-D
H--E--L--L--O----W--O--R--L--D
H--E--L-L--O---W--O--R--L--D----A-N-D----G-O-O--D-B--Y-E
Y--O--U----A--R--E----W-O-N--D-E-R-F-U--L
END;
$lines = explode( PHP_EOL, $text );
foreach( $lines as $key => $line )
{
if( preg_match_all( '/-*/', $line, $matches ) !== false )
{
$counts = array_map( 'strlen', $matches[0] );
if( max( $counts ) >= 3 )
{
$line = preg_replace('/-{3,4}/',' ', $line );
$line = preg_replace('/-{1,2}/','', $line );
}
else
{
$line = replace( '--', ' ', $line );
$line = replace( '-', '', $line );
}
}
echo $line . PHP_EOL;
}
Все, что находится за пределами этих правил, не будет соответствовать, двойные пробелы полностью испортят это.
Печать
HELLO WORLD
HELLO WORLD
HELLO WORLD AND GOODBYE
YOU ARE WONDERFUL
Я хотел добавить подход без зацикливания (но использует какой-то preg, которого я тоже пытался избежать).
Найдите самое длинное непрерывное число пробелов. Токенизируйте строку, разбив ее на «самое большое пространство», чтобы получить массив «слов». Уберите пробел из каждого слова. Положите его обратно вместе.
<?php
function stripSpace($str) {
return str_replace(' ', '', $str);
}
$test = 'H E L L O W O R L D';
//$test = 'H E L L O W O R L D A G A I N';
preg_match_all('#(\s)\1+#', $test, $m);
usort($m[0], function($a, $b) {
return (strlen($a) < strlen($b)) ? 1 : -1;
});
$m = strlen($m[0][0]);
$parts = explode(str_repeat(chr(32), $m), $test);
$parts = array_map('stripSpace', $parts);
echo implode($parts, chr(32));