在段落中将每个句子的第一个字母大写?

In paragraph making the first letter of every sentence uppercase?

我从 php.net 获得了这个函数,用于将句子中的大写字母转换为小写字母。

function sentence_case($string) {
    $sentences = preg_split('/([.?!]+)/', $string, -1, PREG_SPLIT_NO_EMPTY|PREG_SPLIT_DELIM_CAPTURE);
    $new_string = '';
    foreach ($sentences as $key => $sentence) {
        $new_string .= ($key & 1) == 0
            ? ucfirst(strtolower(trim($sentence)))
            : $sentence . ' ';
    }
    return trim($new_string);
}

如果句子不在段落中,一切正常。但如果句子在段落中,开头段落的第一个字母(<p>)或中断(<br>)标记HTML变为小写。

这是样本:

之前:

<p>Lorem IPSUM is simply dummy text. LOREM ipsum is simply dummy text! wHAt is LOREM IPSUM? Hello lorem ipSUM!</p>

输出:

<p>lorem ipsum is simply dummy text. Lorem ipsum is simply dummy text! What is lorem ipsum? Hello lorem ipsum!</p>

谁能帮我把段落的第一个字母变成大写字母?

您可以使用 CSS 轻松完成

p::first-letter {
    text-transform: uppercase;
}

你的问题是你在句子中考虑 HTML,所以句子的第一个 "word" 是 <P>lorem,而不是 Lorem

您可以将正则表达式更改为 /([>.?!]+)/,但这样您会在 "Lorem" 之前看到 额外空格 ,因为系统现在看到 两个个句子而不是一个。

此外,现在Hello <em>there</em>将被视为句。

这看起来很像 "How can I use regexp to interpret (X)HTML"?

试试这个

function html_ucfirst($s) {
return preg_replace_callback('#^((<(.+?)>)*)(.*?)$#', function ($c) {
        return $c[1].ucfirst(array_pop($c));
 }, $s);
}

并调用这个函数

$string= "<p>Lorem IPSUM is simply dummy text. LOREM ipsum is simply dummy text! wHAt is LOREM IPSUM? Hello lorem ipSUM!</p>";
echo html_ucfirst($string);

这是工作演示:https://ideone.com/fNq3Vo

解析有效 html 时,最佳做法是利用合法的 DOM 解析器。使用 regex 不可靠,因为 regex 不知道标签和类似于标签的子字符串之间的区别。

代码:(Demo)

$html = <<<HTML
<p>Lorem IPSUM is simply dummy text.<br>Here is dummy text. LOREM ipsum is simply dummy text! wHAt is LOREM IPSUM? Hello lorem ipSUM!</p>
HTML;

libxml_use_internal_errors(true);
$dom = new DOMDocument();
$dom->loadHTML($html, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
$xpath = new DOMXPath($dom);
foreach($xpath->query('//text()') as $textNode) {
    $textNode->nodeValue = preg_replace_callback(
        '/(?:^|[.!?]) *\K[a-z]+/',
        function($m) {
            return ucfirst($m[0]);
        },
        strtolower($textNode->nodeValue)
    );
}
echo $dom->saveHTML();

输出:

<p>Lorem ipsum is simply dummy text.<br>Here is dummy text. Lorem ipsum is simply dummy text! What is lorem ipsum? Hello lorem ipsum!</p>

以上代码段没有:

  1. 允许首字母缩略词保持全部大写(因为 OP 希望在将 select 个字母大写之前将所有字母转换为小写)
  2. 懒得正确处理多字节字符(因为 OP 没有指出这种必要性)
  3. 不知道句中点和句末点的区别(由于英文标点符号的歧义)