Ellipsis After Certain Number or Characters with Word Boundaries

扶醉桌前 提交于 2019-12-12 18:08:28

问题


I'm trying to put an ellipsis (…) to shorten long descriptions and want to have word boundaries.

Here's my current code eval.in:

# Assume $body is a long text.
$line = $body;
if(strlen($body) > 300 && preg_match('/^.{1,300}\b/su', $body, $match)) {
    $line = trim($match[0]) . "…";
}
echo $line;

This actually works pretty well and I like it except that there are times when the word boundary has a punctuation after it.

If I use the code above, I get results like the following:

This is a long description… or I have punctuations,…. I would love to remove the punctuation after the last word before putting the ellipsis.

Help?


回答1:


Here is your fixed approach:

$body = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam eu congue ex. Nunc sem arcu, fermentum vel feugiat quis, consequat nec enim. Quisque et pulvinar velit, et laoreet justo. Integer quis sapien ac turpis mattis lobortis at at metus. Vestibulum euismod turpis odio, id luctus quam pharetra, at, et. Sed finibus, nunc at ultricies posuere, dui mauris aliquet quam, eget aliquet ligula libero a turpis. Pellentesque eu diam sodales, sollicitudin leo et, sagittis magna. Donec feugiat, velit quis condimentum porttitor, enim sapien varius elit, sit amet pretium risus turpis vitae massa. Sed ac ligula sit amet lorem scelerisque tristique a id ex. Nullam maximus tincidunt magna, vel molestie lectus tempus non. Sed euismod placerat ultricies. Morbi dapibus augue ut odio faucibus, vel maximus nisl pharetra. Aliquam hendrerit dolor in ipsum pharetra, eget tincidunt lacus ultrices.";

$line = $body;
if(strlen($body) > 300 && preg_match('/^(.{1,300})(?!\w)\b\p{P}*/su', $body, $match)) {
    $line = trim($match[1]) . "…";
}
echo $line;

See eval.in demo

As I noted in the comments, you can match the punctuation (optionally, with \p{P}*), but I forgot that \b can match both trailing and leading word boundary. By restricting the \b with the negative lookahead (?!\w) (like (?!\w)\b) we only match the trailing word boundary.

Besides, the capturing group ((...)) is added to the pattern so that we only capture into Group 1 the string with trailing punctuation trimmed out, and the value can be accessed with $match[1].




回答2:


You can use:

$body = preg_replace('/^(.{0,299}\w)\b.*/su', '$1…', $body);
  • Regex Demo
  • Code Demo

\w before \b ensures we don'e add ellipsis after a non-word character



来源:https://stackoverflow.com/questions/35023508/ellipsis-after-certain-number-or-characters-with-word-boundaries

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!