| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > Perl: Регулярные выражения > Как обрезать строку до не разбивая слов |
| Автор: sir_nuf_nuf 5.10.2009, 14:06 |
| Товарищи, хочу предложить вам жизненную задачу на регулярки: Задача проста: Нужно обрезать строку до заданной длинны, стараясь по возможности не разбивать слова. В конце строки нужно дописать троеточие (типа "есть продолжение") Требование: 1) результат, вместе троеточием должен быть не длиннее указанной числа символов 2) не разбивать слова, т.е. обрезать предложение нужно между словю 3) между последним словом и троеточием не должно быть пробелов. Я пока решил эту задачу на if - решил не извращаться с регуляркой. Кто сможет написать regexp ? |
| Автор: gcc 5.10.2009, 14:38 | ||||
| а что должно получиться? вот например я делал обрезать длинные слова и длинные строки...
так вот вызвать:
|
| Автор: shamber 5.10.2009, 15:21 |
| gcc, это регулярка? |
| Автор: gcc 5.10.2009, 15:35 |
| shamber, точно нет... |
| Автор: sir_nuf_nuf 5.10.2009, 16:01 | ||
должно получиться примерно следующее:
|
| Автор: KSURi 5.10.2009, 19:21 | ||||
Легко можно сделать жадный вариант (нарушает п. 1, но на всякий случай):
|
| Автор: sir_nuf_nuf 5.10.2009, 23:18 |
| KSURi, не работает. видно на 'This is very-very-very-very-very long string. Really long.' |
| Автор: amg 6.10.2009, 07:03 | ||
Вот что я придумал (правда, не только регулярка, плюс к ней еще pos и пробелы в начале строки нужно удалять)
|
| Автор: gcc 6.10.2009, 07:29 |
| а почему нельзя написать без регулярки? регулярка быстрее будет? просто пока это все понапридумывать - так очень много времени тратиться на это |
| Автор: arto 6.10.2009, 14:42 |
| perl -le 'print $ARGV[0] =~ m#^(.{15,24}\S)\b# ? "$1..." : $ARGV[0]' |
| Автор: Logo 8.10.2009, 09:15 | ||||
А что считать словом? Машинное слово? Тогда:
Что бы развить моск. При тренировке регулярками как правило наоборот, время меньше тратится. |
| Автор: amg 8.10.2009, 10:43 |
| Logo, а если $_ = 'This_is_very_very_very_very_very_long_word.'; |
| Автор: Logo 8.10.2009, 13:10 | ||
| amg, Можно добавить
|
| Автор: amg 8.10.2009, 15:37 |
| Не помогает. Все равно длинное слово вырезается полностью. (хотя в условии, строго говоря, не сказано, что такого быть не должно, но исходя из здравого смысла, логично было бы оставлять часть слова). Кроме того, пусть, например, строка содержит ровно $maxn символов. Твоё решение такую строку обрежет. А логично было бы оставить ее как есть -- она же помещается. И к совсем коротким словам добавит ... Еще одну проверку? (В условии то сказано "только регуляркой". Хотя этого никто пока не смог соблюсти). |
| Автор: Logo 8.10.2009, 16:11 | ||||||
Ну да, я и поправил только некорректное не обявленное значение переменной.
Верно, и если она меньше $maxn... Сама регуляка только делает "результат, вместе троеточием должен быть не длиннее указанной числа символов". Можно поставить if на длинну строки в коде, хотя и регуляркой тоже можно
|
| Автор: Logo 10.10.2009, 13:50 | ||||||
Одной регуляркой, и с учетом пожеланий amg. Хотя это уже изврат, наверное
Хотя на мой взгляд, если разбивать, то не по длине слова, а по длине части слова, оказавшейся целой.
Про это непонял |
| Автор: ad280379 2.12.2009, 08:27 | ||
помоему это есть наиболее правильное решение на основе регулярных выражений. единственно не понимаю (т.е. считаю что не правильно) указание \S (вместо \s) и не понятно зачем нижняя граница {15,24} я переписал это так (в данном решении N количество выводимых символов) формат - prg_name.pl N "Hello and welcome dears" результат при N=10 будет "Hello and ..." ---code--- $text = $ARGV[1]; $ltext = length($ARGV[1]); print "[$ltext],[$ARGV[0]],$text" if($text=~m/^(.{0,$ARGV[0]}\s*)\b/ ? ($text="$1...") : ($text.="...")); ---code end--- конструктивная критика приветствуется |
| Автор: Logo 12.12.2009, 22:09 | ||
Очень коротко и аргументировано |
| Автор: ad280379 12.12.2009, 23:52 | ||||
ну... вы же Бывалый... вообще должны с двух слов понимать |
| Автор: amg 14.12.2009, 12:06 |
| Господа! По моему, мы несколько неправильно понимаем задачу. Насколько я себе представляю, она состоит не в том, чтобы написать код, делающий сформулированные в 1-м посте вещи, и даже не в том, чтобы этот код был самым коротким/изящным, а в том, чтобы сделать это только ругуляркой. И такая постановка задачи, IMHO, так пока и не решенной, оправдана. Во-первых, тогда решение будет почти прямо переносимо на любой ЯП, где есть PCRE, во-вторых, существуют программы a'la grep, которым на вход нужно давать регулярное выражение и ничего кроме него. |
| Автор: Logo 14.12.2009, 23:09 | ||
А как же мой код |
| Автор: amg 16.12.2009, 11:16 |
| И в самом деле. А я твой код как-то пропустил, т.к. после беглого взгляда на него он у меня не ассоциировался с регулярным выражением (они обычно не так выглядят) |
| Автор: ad280379 16.12.2009, 20:11 | ||||
А как же мой код |