在段落中将每个句子的第一个字母大写?
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>
以上代码段没有:
- 允许首字母缩略词保持全部大写(因为 OP 希望在将 select 个字母大写之前将所有字母转换为小写)
- 懒得正确处理多字节字符(因为 OP 没有指出这种必要性)
- 不知道句中点和句末点的区别(由于英文标点符号的歧义)
我从 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>
以上代码段没有:
- 允许首字母缩略词保持全部大写(因为 OP 希望在将 select 个字母大写之前将所有字母转换为小写)
- 懒得正确处理多字节字符(因为 OP 没有指出这种必要性)
- 不知道句中点和句末点的区别(由于英文标点符号的歧义)