Mam fragment kodu napisany w języku PHP, który pobiera blok tekstu z bazy danych i wysyła go do widżetu na stronie internetowej. Oryginalnym blokiem tekstu może być długi artykuł lub krótkie zdanie lub dwa; ale dla tego widżetu nie mogę wyświetlić więcej niż, powiedzmy, 200 znaków. Mógłbym użyć substr (), aby odciąć tekst przy 200 znakach, ale rezultatem byłoby odcięcie w środku słów - tak naprawdę chcę, aby wyciąć tekst na końcu ostatniego słowa przed 200 znakami.
183
s($str)->truncateSafely(200)
Pomocne mogą być informacje zawarte w tej niezależnej bibliotece .Odpowiedzi:
Korzystając z funkcji zawijania tekstu . Dzieli tekst na wiele wierszy, tak aby maksymalna szerokość była tą, którą określiłeś, zrywając na granicach słów. Po podzieleniu wystarczy wziąć pierwszą linię:
Jedną z rzeczy, których ten oneliner nie obsługuje, jest to, że sam tekst jest krótszy niż pożądana szerokość. Aby obsłużyć ten przypadek na krawędzi, należy zrobić coś takiego:
Powyższe rozwiązanie ma problem z przedwczesnym wycinaniem tekstu, jeśli zawiera on nową linię przed rzeczywistym punktem odcięcia. Oto wersja rozwiązująca ten problem:
Również tutaj jest klasa testowa PHPUnit używana do testowania implementacji:
EDYTOWAĆ :
Specjalne znaki UTF8, takie jak „à”, nie są obsługiwane. Dodaj „u” na końcu REGEXU, aby go obsłużyć:
$parts = preg_split('/([\s\n\r]+)/u', $string, null, PREG_SPLIT_DELIM_CAPTURE);
źródło
\n
przed nim pożądana szerokość.Arabic
pomogło , mój ból głowy składał się z długich liter i został zredukowany do poprawnych słów teraz za pomocątokenTruncate
funkcji .. tnx milion :)Zwróci to pierwsze 200 znaków słów:
źródło
if (strlen($string) > $your_desired_width) { preg_replace(...); }
/\s+?(?:\S+)?$/
I oto masz - niezawodna metoda skracania dowolnego ciągu do najbliższego całego słowa, przy zachowaniu maksymalnej długości łańcucha.
Próbowałem innych przykładów powyżej i nie przyniosły one pożądanych rezultatów.
źródło
if
oświadczeniu:if (strlen($str) > 200) { ... }
$WidgetText = substr($string, 0, strpos($string, ' ', 200));
Poniższe rozwiązanie narodziło się, gdy zauważyłem parametr $ break funkcji zawijania słów :
Oto rozwiązanie :
Przykład 1.
Powyższy przykład wyświetli:
Przykład nr 2.
Powyższy przykład wyświetli:
źródło
description
post z bloga)preg_replace('/\s+/', ' ', $description)
aby zastąpić wszystkie znaki spacji pojedynczą spacją;)Pamiętaj, ilekroć dzielisz słowo na słowo w dowolnym miejscu, w którym niektóre języki, takie jak chiński i japoński, nie używają spacji do dzielenia słów. Ponadto złośliwy użytkownik może po prostu wpisać tekst bez spacji lub użyć trochę podobnego do Unicode standardowego znaku spacji, w którym to przypadku każde zastosowane rozwiązanie może i tak wyświetlić cały tekst. Obejściem tego może być sprawdzenie długości łańcucha po normalnym podzieleniu go na spacje, a następnie, jeśli łańcuch jest nadal powyżej nienormalnego limitu - w tym przypadku może być to 225 znaków - idąc dalej i głupio dzieląc go na tym limicie.
Jeszcze jedno zastrzeżenie związane z takimi rzeczami, jeśli chodzi o znaki spoza ASCII; ciągi zawierające je mogą być interpretowane przez standardową strlen () PHP jako dłuższe niż są w rzeczywistości, ponieważ pojedynczy znak może zająć dwa lub więcej bajtów zamiast tylko jednego. Jeśli po prostu użyjesz funkcji strlen () / substr () do podzielenia ciągów, możesz podzielić ciąg w środku znaku! W razie wątpliwości mb_strlen () / mb_substr () są nieco bardziej niezawodne.
źródło
Użyj strpos i substr:
To da ci łańcuch obcięty na pierwszym miejscu po 30 znakach.
źródło
Proszę bardzo:
źródło
Oto moja funkcja oparta na podejściu @ Cd-MaN.
źródło
Opis:
^
- zacznij od początku łańcucha([\s\S]{1,200})
- zdobądź od 1 do 200 dowolnej postaci[\s]+?
- nie dołączaj spacji na końcu krótkiego tekstu, abyśmyword ...
zamiast tego mogli uniknąćword...
[\s\S]+
- dopasuj wszystkie inne treściTesty:
regex101.com
dodajmy door
kilku innychr
regex101.com
orrrr
dokładnie 200 znaków.regex101.com
po piątymr
orrrrr
wykluczone.Cieszyć się.
źródło
$1
jest to „zamiennik”, ale w tym konkretnym kontekście do czego to odnosi się ?? pusta zmienna?$1
nawiązująca do nawiasów([\s\S]{1,200})
.$2
będzie odwoływał się do dwóch sekund pary nawiasów, jeśli występują we wzorze.Zaskakujące jest, jak trudno jest znaleźć idealne rozwiązanie tego problemu. Nie znalazłem jeszcze odpowiedzi na tej stronie, która nie zawodzi, przynajmniej w niektórych sytuacjach (zwłaszcza jeśli ciąg znaków zawiera znaki nowej linii lub tabulatory, lub jeśli słowo przerwa jest czymś innym niż spacja, lub jeśli ciąg ma UTF- 8 znaków wielobajtowych).
Oto proste rozwiązanie, które działa we wszystkich przypadkach. Były tutaj podobne odpowiedzi, ale modyfikator „s” jest ważny, jeśli chcesz, aby działał z wejściem wieloliniowym, a modyfikator „u” sprawia, że poprawnie ocenia znaki wielobajtowe UTF-8.
Jeden możliwy przypadek krawędzi z tym ... jeśli ciąg nie ma w ogóle żadnych białych znaków w pierwszych znakach $ characterCount, zwróci cały ciąg. Jeśli wolisz, że wymusza przerwanie na $ characterCount, nawet jeśli nie jest to granica słów, możesz użyć tego:
Ostatnia opcja, jeśli chcesz, aby dodała wielokropek, jeśli obcina ciąg ...
źródło
Użyłbym do tego funkcji preg_match, ponieważ to, czego chcesz, jest dość prostym wyrażeniem.
Wyrażenie oznacza „dopasuj dowolny podciąg zaczynający się od początku długości 1-200, kończący się spacją”. Wynik jest w $ wynik, a dopasowanie jest w $ dopasowaniach. To dotyczy twojego pierwotnego pytania, które kończy się na każdej przestrzeni. Jeśli chcesz, aby skończył się na nowej linii, zmień wyrażenie regularne na:
źródło
Ok, więc dostałem kolejną wersję tego opartą na powyższych odpowiedziach, ale biorąc pod uwagę więcej rzeczy (utf-8, \ n i & nbsp;), również wiersz usuwający skomentowane skróty wordpress, jeśli są używane z wp.
źródło
To jest mała poprawka dla odpowiedzi Mattmac:
Jedyną różnicą jest dodanie spacji na końcu ciągu $. Dzięki temu ostatnie słowo nie jest ucięte zgodnie z komentarzem ReX357.
Nie mam wystarczającej liczby punktów powtórzeń, aby dodać to jako komentarz.
źródło
Stosowanie:
Spowoduje to wyświetlenie pierwszych 10 słów.
preg_split
Funkcja służy do podzielić ciąg na podciągi. Granice, wzdłuż których ciąg ma zostać podzielony, są określone przy użyciu wzorca wyrażeń regularnych.preg_split
funkcja przyjmuje 4 parametry, ale tylko pierwsze 3 są teraz dla nas istotne.Pierwszy parametr - wzorzec Pierwszy parametr to wzorzec wyrażeń regularnych, wzdłuż którego ma zostać podzielony ciąg. W naszym przypadku chcemy podzielić ciąg znaków na granice słów. Dlatego używamy predefiniowanej klasy znaków,
\s
która pasuje do białych znaków, takich jak spacja, tabulator, znak powrotu karetki i przesunięcie wiersza.Drugi parametr - ciąg wejściowy Drugi parametr to długi ciąg tekstowy, który chcemy podzielić.
Trzeci parametr - limit Trzeci parametr określa liczbę podciągów, które powinny zostać zwrócone. Jeśli ustawisz limit na
n
, preg_split zwróci tablicę n elementów. Pierwszen-1
elementy będą zawierać podciągi. Ostatni(n th)
element będzie zawierał resztę ciągu.źródło
Na podstawie wyrażenia regularnego @Justin Poliey:
źródło
Mam funkcję, która robi prawie wszystko, co chcesz, jeśli wykonasz kilka edycji, będzie pasować dokładnie:
źródło
Oto jak to zrobiłem:
źródło
Wiem, że to jest stare, ale ...
źródło
Tworzę funkcję bardziej podobną do substr i używając idei @Dave.
Ps .: Cięcie na całej długości może być mniejsze niż podłoże.
źródło
Dodano instrukcje IF / ELSEIF do kodu od Dave'a i AmalMurali do obsługi ciągów znaków bez spacji
źródło
Uważam, że działa:
funkcja abbreviate_string_to_whole_word ($ string, $ max_length, $ buffer) {
}
Bufor pozwala dostosować długość zwracanego ciągu.
źródło
Użyj tego:
następujący kod usunie „,”. Jeśli masz inny znak lub podciąg, możesz użyć tego zamiast „,”
// jeśli masz inne konto string dla
źródło
Chociaż jest to dość stare pytanie, pomyślałem, że przedstawię alternatywę, ponieważ nie zostało to wspomniane i ważne dla PHP 4.3+.
Możesz użyć
sprintf
rodziny funkcji do obcięcia tekstu za pomocą%.ℕs
modyfikatora dokładności.Proste obcinanie https://3v4l.org/QJDJU
Wynik
Rozszerzone obcinanie https://3v4l.org/FCD21
Ponieważ
sprintf
działa podobniesubstr
i częściowo odcina słowa. Poniższe podejście zapewni, że słowa nie zostaną odcięte przy użyciustrpos(wordwrap(..., '[break]'), '[break]')
specjalnego separatora. To pozwala nam odzyskać pozycję i upewnić się, że nie pasujemy do standardowych struktur zdań.Zwracanie ciągu bez częściowego odcinania słów, który nie przekracza określonej szerokości, z zachowaniem podziału linii w razie potrzeby.
Wynik
Wyniki za pomocą
wordwrap($string, $width)
lubstrtok(wordwrap($string, $width), "\n")
źródło
Użyłem tego wcześniej
źródło
Tutaj możesz spróbować
źródło
Uważam, że to najłatwiejszy sposób:
Używam znaków specjalnych do podziału tekstu i wycięcia go.
źródło
Może to pomoże komuś:
źródło