LINUX.ORG.RU

Яр - какие ф-ии работы со строками включить в стандартную библиотеку?

 


0

1

Вот можно взять из 1С, там мало и просто.

Можно гнаться за tcl, там много и хорошо.

Можно взять то, что уже есть в лиспе и самых ходовых библиотеках, но там явно не хватает таких простых вещей, как «взять эн буковок справа». И большой вопрос - как русифицировать названия.

Иными словами, в каком языке самая лучшая (и при этом маленькая) библиотека работы со строками?

-константы типа ascii_chars, как в Питоне
-Извлечение букв по индексу
-Преобразование кодировок
-Транслитерация
-Базовые ожидаемые функции: подстрока, трим, пад, замена по индексу, замена по подстроке
-Форматный вывод (наверное, надо сделать как объект
 форматтер в питоне или как моя cons-to-source.lisp ) 
-Обработка русского языка (падежи и пр) 
-парсинг (взять из языка ред или мой нано-парсер)
-конкатенация
-сравнение
-объект ТекстовыйДокумент ≈ ed
★★★★★

Последнее исправление: den73 (всего исправлений: 3)

В Allegro был вариант человекочитемых регулярок. И это наверное наверное практичнее чем 100 вариантов «взять эн буковок справа»
ну и sed уже придуман. Перепиши список команд и будет тебе счастье.

antares0 ★★★★
()
Последнее исправление: antares0 (всего исправлений: 2)
Ответ на: комментарий от no-such-file

В CL обычно быстрее. Куски компилятора доступные в рантайме убирают ненужные ветки исполнения. Применительно к чему-то уровня SBCL.

antares0 ★★★★
()
Последнее исправление: antares0 (всего исправлений: 1)
Ответ на: комментарий от antares0

Блин, когда-нибудь будет простой вопрос? Массово советуют регулярки, но для меня это больная тема. Для простоты можно сказать, что я их не осилил, но вот мои аргументы против регэкспов вообще.

Мне не нравятся регекспы чем?

1. У них нет стандарта, поэтому в каждой новой среде приходится мучаться с нюансами и читать гигантские мануалы. Вот пример, чем реализация регекспов для лиспа отличается от таковой для перла

2. Они являются языком программирования, но в них нет переменных и подпрограмм. Есть некие костыли, подобные частному случаю переменных (с номерами вместо имён), а для подпрограмм надо строить сам регэксп конкатенацией строк, т.е. он перестаёт быть литералом. Поэтому регэкспы не масштабируемы - ими удобно решать только маленькие и простые задачи.

3. Они являются средством создания парсеров, причём сложным. Сложно то, что парсер может быть жадным и не жадным. Ставим рядом несколько жадных и не жадных и я уже ничего не понимаю. Если вы понимаете - я за вас рад.

4. Они состоят из кучи спец-значков. Если нужно вписать регэксп в командной строке, или в строковом литерале, или преобразовать из одного языка в другой, возникают заросли из обратных кавычек. Да, можно набить руку, но можно и задаться вопросом: а ради чего такие муки?

5. В обычной жизни всегда есть «отладка принтами». Вставь одну букву в регэксп - и это уже тот регэксп. Но в языке программирования регэкспов нет команды «напечатай в stderr», нужно сильно менять тот код, к-рый вызывает этот регэксп. Есть программы типа regexbuddy Но если пользуешься внешней программой, может быть всё равно не так легко решить вопрос «а почему эта сука в моём гигабайте находит только 180 вхождений из 200», ведь нужно же ещё и подсунуть ей именно мои данные, а для этого нужна именно трассировка в боевом окружении, а не сторонняя программа.

В общем, регэкспов в ближайшей версии Яра не будет. Видимо, для компенсации их отсутствия нужна какая-то библиотека для генерации парсеров, но более удобная, чем регулярки.

В Allegro был вариант человекочитемых регулярок.

Почему только в аллегро? А в cl-ppcre разве не то?

Человекочитаемые регулярки чуть лучше, чем просто регулярки, особенно ввиду того, что с помощью квазицитат можно добавить в них хотя бы подпрограммы и (может быть) трассировку.

strlcpy & strlcat - обожаю эту парочку!

Лисп более высокоуровневый, хотя, наверное, можно что-то подобное навелосипедить. Сейчас вообще норовят сделать немутабельные строки (хотя я не сторонник этого). Аналогом этого являются потоки записи в строку, но строка вроде бы не может быть ограничена - среда её расширяет по мере надобности.

А зачем именно маленькая? Не является ли целью сделать работу со строками удобной?

Является целью выдать версию ранее, чем меня отнесут на кладбище.

Яр — это то, что раньше было «кодица»?

Да, подправь свой список.

left-pad

Спасибо. Прекрасная библиотека и прекрасная история. Правда, парень зря дал слабину. Не знаю, как я бы поступил на его месте, но он по сути струсил, испугался слова «юрист». Не надо было так делать. Может, они бы и не прислали к нему юристов, да юристы и не киллеры, может он бы и отбрехался от них как-то. Круги на воде быстро разойдутся, а имя он потерял.

ИТАК, пока что проект API выглядит так:

1. Как-то преобразовать в строку 
2. Аналог format, printf и пр. Хотя в лиспе формат тоже 
какой-то криптографический и страдает теми же недостатками,
что и регулярки. У меня была библиотечка вывода, когда 
строится дерево cons-ов, содержащее команды, а потом дерево
выводится. Медленнее, зато более человечно.

3. Функции из 1С (названия вряд ли уцелеют)

СокрЛП, Лев, Прав, Сред, "подстрока по номерам справа", СтрДлина 
(а вот мне почему-то не нравится "строка".Длина
, почему - не могу понять, но может быть и сойдёт). 

найти букву в строке по предикату, возвращая найденную букву или её смещение. 

ВРег, НРег, trim-left, trim-right, pad-left, pad-right .

Поток вывода в строку (with-output-to-string)

split (аналог перлового или split-sequence:split-sequence из лиспа)

заменить кусок текста от и до на такой-то иной кусок. 

поиск с заменой, можно передавать ему предикат для сравнения букв. 

операции конкатенации:

♥ - конкатенация только строк
♥♥ - преобразование в строку любых аргументов и конкатенация полученных строк

Преобразовать строку в односвязный список (а так строка в
лиспе это массив). 

Цикл по элементам строки. 
Цикл по подстрокам строки, битой по предикату (например,
 по литере конца строки)

Пока что дыра в том месте, где регулярные выражения и scanf. Для этой цели, я думаю, нужно проэкспортировать те парсеры, к-рыми я разбираю сам Яр. Это метод рекурсивного спуска с возможностью установки временных закладок (часть потока от самой ранней действительной закладки кешируется в памяти), а также PEG, плюс набор примитивов типа «прочитать число». Опять же, это будет не особо быстро.

Ну и очень удобно работать в программируемом текстовом редакторе, где можно ставить марки (теги) на текст, к-рые ездят после изменений текста. Т.е. можно сначала всё разметить, а потом менять, и марки будут сами ездить. Опять же это может быть медленно, зато очень удобно. Может быть, нужно сделать какой-то объект «буфер с марками», более легковесный, чем буфер редактора.

Извините, много букв получилось, и я уже устал :(

den73 ★★★★★
() автор топика
Последнее исправление: den73 (всего исправлений: 2)
Ответ на: комментарий от den73

Далее, что в Питоне?

1. Много хороших констант, напиример, ascii_lowercase. Надо сделать.

2. Срезы - это сахар, интересный, но мне значков жаль на него. Можно сделать псевдо-ф-ии.

3. Класс formatter. В принципе интересно, вопрос - насколько это популярно?

4. template - мне не понравилось - слишком убого.

5. интересно: encode,decode,maketrans,translate,endswith,join (надо добавить необязательный параметр «разделитель»),

den73 ★★★★★
() автор топика
Ответ на: комментарий от den73

Почему только в аллегро? А в cl-ppcre разве не то?

То. Мне почему то именоо Allegro вспомнился. Они чуть понятнее подали эту идею. А ppcre у меня всегдя ассациировался с нечитаемыми закорючками:(

antares0 ★★★★
()
Ответ на: комментарий от Hertz

Это парсеры на комбинаторах, если я правильно понял. Вот здесь перечислены недостатки этого подхода. Правда написана или нет?

den73 ★★★★★
() автор топика
Ответ на: комментарий от den73

1. У них нет стандарта, поэтому в каждой новой среде приходится мучаться с нюансами и читать гигантские мануалы. Вот пример, чем реализация регекспов для лиспа отличается от таковой для перла

По ссылке описания нескольких багов, найденных в реализации перла во время работы над cl-ppcre. Семантические отличия там не описаны.

Единого стандарта у регулярных выражений действительно нет, но, насколько мне известно, перловые являются надмножеством по возможностям над всеми остальными, поэтому я бы взял их.

2. Они являются языком программирования, но в них нет переменных и подпрограмм. Есть некие костыли, подобные частному случаю переменных (с номерами вместо имён), а для подпрограмм надо строить сам регэксп конкатенацией строк, т.е. он перестаёт быть литералом. Поэтому регэкспы не масштабируемы - ими удобно решать только маленькие и простые задачи.

Зато с маленькими и простыми задачами они справляются на ура. Особенно когда есть поддержка со стороны синтаксиса, как в перле.

4. Они состоят из кучи спец-значков. Если нужно вписать регэксп в командной строке, или в строковом литерале, или преобразовать из одного языка в другой, возникают заросли из обратных кавычек.

Это плата за возможность компактно написать целый конечный автомат для разбора строки. Реализация через аналоги strtok будет длиннее и непонятнее. В лиспе, кстати, не составит труда ввести оператор q{} из перла, который сводит дополнительное экранирование к нулю. cl-interpol упрощает сборку строк, если не нравится format.

5. В обычной жизни всегда есть «отладка принтами».

В перле есть use re 'debugcolor', который делает ровно то, что ты хочешь. Запили в своей реализации.

По пунктам 2 и 3 --- масштабируемость, подпрограммы и сложность --- посмотри на грамматики в perl6. У меня нет опыта работы с ними, но, судя по описанию, они снимают твои возражения. Если сможешь перенести их в Яр (или в CL), будет круто.

Кстати, если есть удобные регулярные выражения, все остальные функции для работы со строками, в общем-то, можно выкинуть. Ну разве что оставить низкоуровневые вещи для скорости и альтернативных реализаций.

Jini ★★
()
Ответ на: комментарий от Jini

Спасибо. Думаю, если это «баги» в перле, то они являются де-факто стандартом и нужна багосовместимость.

Я согласен, что регэкспы хороши для маленьких задач. Но тогда получается, что нужен ещё один механизм для больших задач.

Видимо, в Перле для этой цели предлагаются грамматики. Вот вы не дошли до грамматик в Перле, а если бы сразу были только грамматики и не было регэкспов, то вы бы начали с грамматик, освоили бы их, уровень владения языком был бы выше. Да, с библиотекой парсеров где-то придётся писать больше букв, ну и не страшно. Можно ведь сокращать функционал разным способом, делать функции, макросы и пр.

Касаемо perldebug, уклониться от сложности тут не выходит:

use re 'debug' enables you to see the gory details of how the Perl regular expression engine works. In order to understand this typically voluminous output, one must not only have some idea about how regular expression matching works in general, but also know how Perl's regular expressions are internally compiled into an automaton. These matters are explored in some detail in Debugging Regular Expressions in perldebguts.

Сразу начинает казаться, что это некий «неуправляемый trace», который потом ещё нужно фильтровать. Т.е. всё равно не слишком хороший отладчик (возможно, я придираюсь).

Думается, единственный выход здесь - это сделать машину парсера более простой. Предоставить примитивы, а пользователь пусть пишет процедуры разбора. Во всяком случае, я написал несколько парсеров для ЯП и мне кажется, что так удобнее всего. Желательно иметь несколько машин парсеров, т.к. для разных задач лучше подходят разные техники.

За cl-interpol спасибо, посмотрю.

den73 ★★★★★
() автор топика
Ответ на: комментарий от den73

Думаю, если это «баги» в перле, то они являются де-факто стандартом и нужна багосовместимость.

Там какие-то крайние случаи, вряд ли ими кто-то пользуется. Я думаю, лучше ориентироваться на документацию.

Я согласен, что регэкспы хороши для маленьких задач. Но тогда получается, что нужен ещё один механизм для больших задач.

Набор функций типа trim-left и pad-right не прокатит в качестве такого механизма. Грамматики Perl6 или встроенные комбинаторные парсеры --- может быть, но их сделать сложнее регулярных выражений, для которых уже есть готовая библиотека. Вообще, большие задачи требуют индивидуального подхода, и сделать хороший универсальный инструмент сложно.

Вот вы не дошли до грамматик в Перле, а если бы сразу были только грамматики и не было регэкспов, то вы бы начали с грамматик, освоили бы их, уровень владения языком был бы выше.

Грамматики (встроенные) появились только в Perl6, который вышел относительно недавно. Perl5 и Perl6 это два разных языка, как C и C++. Я ещё не успел поработать с Perl6, хотя у меня есть одна идея, для которой он неплохо подходит. В Perl6 нет классических регэкспов, но грамматики, насколько я понял, с ними частично совместимы. Так что в Perl6 придётся начинать с грамматик.

Сразу начинает казаться, что это некий «неуправляемый trace», который потом ещё нужно фильтровать.

Там действительно довольно много текста, но разобраться в нём несложно, достаточно вспомнить, что регулярные выражения строят конечный автомат. Найти ошибку с такой подробной выдачей не составляет труда. Если вы будете делать свою реализацию, то можно добавить управление над выдачей с помощью локальных биндингов динамических переменных. (Хм, интересно, можно ли отлаживать регулярные выражения, вызывая trace на внутренние функции cl-ppcre...).

Думается, единственный выход здесь - это сделать машину парсера более простой. Предоставить примитивы, а пользователь пусть пишет процедуры разбора. Во всяком случае, я написал несколько парсеров для ЯП и мне кажется, что так удобнее всего. Желательно иметь несколько машин парсеров, т.к. для разных задач лучше подходят разные техники.

Это должно быть просто в использовании. Сложно представить что-то проще чем /^\s*$/ для проверки пустых строк. Мелкие задачи редко требует контекстно-свободной грамматики, регулярной вполне достаточно.

Ладно, я просто хотел сказать, что вы недооцениваете регулярные выражения. Что встраивать в Яр --- это ваша забота, так как только вы можете сделать выбор между своими желаниями и возможностями.

Jini ★★
()
Ответ на: комментарий от den73

Не уверен. Сам пока не разобрался (в планах). Но ракетовскую либу markdown использую и как слон доволен. // Регулярки сам не люблю, но что поделать.

Hertz ★★★★★
()
Ответ на: комментарий от Hertz

Грамматики Perl6 или встроенные комбинаторные парсеры --- может быть, но их сделать сложнее регулярных выражений, для которых уже есть готовая библиотека. Вообще, большие задачи требуют индивидуального подхода, и сделать хороший универсальный инструмент сложно.

В данном случае сложность изготовления я хочу сэкономить за счёт заимствования кода (даже я написал свой, так скажем, фреймворк для создания парсеров, когда делал парсер Яра, и ещё куча готовых библиотек есть). Качество мне более важно.

Набор функций типа trim-left и pad-right не прокатит в качестве такого механизма.

Обычно там, где настоящий программист возьмёт регулярки (о боже, в каком я состоянии, вместо «регулярки» написал «виртуалки»), я буду действовать split-ами. Да. Для полноценной замены регулярок нужен какой-то генератор парсеров или что-то в этом роде (я пока склоняюсь к созданию инфраструктуры для создания парсеров методом рекурсивного спуска с возможностью сохранения части потока в памяти. Это даёт возможность отката и контроль над затратами памяти, т.е. получается очень простое и прямолинейное решение задачи парсинга. Ну а вообще да, нужно несколько инструментов, например, выражения я разбирал PEG-ом - совершенно отдельный код.

Найти ошибку с такой подробной выдачей не составляет труда

Я просто зачастую не понимаю, что делают регэкспы. Если стоят рядом жадный и не жадный парсер, то я не понимаю, как они взаимодействуют. Да и вообще в них полно всяких глобальных модификаторов, все их нужно учитывать. Регэкспы сложны и на практике лично я стараюсь сохранять регулярки и использовать их повторно,а не пытаться понять, как их писать. Впрочем, я ими почти не пользуюсь.

Сложно представить что-то проще чем /^\s*$/ для проверки пустых строк

Ну да, это некая идиома, к-рую просто запоминаешь. Она короткая (мало букв) - в этом её гигантский плюс. Но предел постижимости по сложности лично для меня наступает очень быстро.

den73 ★★★★★
() автор топика
Последнее исправление: den73 (всего исправлений: 1)
Ответ на: комментарий от Hertz

Не уверен. Сам пока не разобрался (в планах).

А мне кажется, похоже на правду (про недостатки комбинаторов)

den73 ★★★★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.