У меня есть функция, которая должна делать первый символ всех предложений заглавными, но по какой-то причине он не делает это с первым символом первого предложения. Почему это происходит, и как мне это исправить?
<?php
function ucAll($str) {
$str = preg_replace_callback('/([.!?])\s*(\w)/',
create_function('$matches', 'return strtoupper($matches[0]);'), $str);
return $str;
} //end of function ucAll($str)
$str = ucAll("first.second.third");
echo $str;
?>
Результат:
first.Second.Third
Ожидаемый результат:
First.Second.Third
Это не прописные буквы первого слова, потому что регулярное выражение требует, чтобы было одно из .
, !
или же ?
перед ней. У первого слова нет ни одного из этих символов перед ним.
Это сделало бы это:
function ucAll($str) {
return preg_replace_callback('/(?<=^|[\.\?!])[^\.]/', function ($match) {
return strtoupper($match[0]);
}, $str);
}
Он использует позитивный взгляд, чтобы убедиться, что один из .
, !
, ?
или начало строки перед сопоставляемой строкой.
Попробуй это
function ucAll($str) {
$str = preg_replace_callback('/([.!?])\s*(\w)|^(\w)/',
create_function('$matches', 'return strtoupper($matches[0]);'), $str);
return $str;
} //end of function ucAll($str)
$str = ucAll("first.second.third");
echo $str;
|^(\w)
это «или получить первый символ»
Что-то вроде этого :
function ucAll($str) {
$result = preg_replace_callback('/([.!?])\s*(\w)/',function($matches) {
return strtoupper($matches[1] . ' ' . $matches[2]);
}, ucfirst(strtolower($str)));
return $result;
} //end of function ucAll($str)
$str = ucAll("first.second.third");
echo $str;
Выход :
Первый. Во-вторых. В третьих
Это происходит потому, что ваше регулярное выражение соответствует только символам после определенного вами набора знаков препинания, а первое слово не следует за одним из них. Я бы предложил внести эти изменения:
Во-первых, эта группа ([?!.]|^)
соответствует началу строки (^
), а также ваш список знаков препинания перед (необязательными) пробелами и символом слова, который вы пытаетесь заменить. Установка этого способа означает, что он все еще должен работать, если в начале строки есть пробел.
Во-вторых, используя анонимную функцию вместо create_function
является рекомендуемые если вы используете PHP> = 5.3, которым, как мы надеемся, вы занимаетесь в данный момент (если вы этого не сделаете, простое изменение регулярного выражения в вашей функции должно работать).
function ucAll($str) {
return preg_replace_callback('/([?!.]|^)\s*\w/', function($x) {
return strtoupper($x[0]);
}, $str);
}
Я обновил ваше регулярное выражение и использовал ucwords
вместо strtoupper
как
function ucAll($str) {
return preg_replace_callback('/(\w+)(?!=[.?!])/', function($m){
return ucwords($m[0]);
}, $str);
}
$str = ucAll("first.second.third");
echo $str;