LINUX.ORG.RU

[haskell] Регулярные выражения

 


0

1

Есть две задачи, которые в perl делал при помощи сабжа: если строка начинается с правильного слова и заканчивается правильным словом, тогда извлечь из строки подстроку соответствующею заданному выражению и если строка содержит правильное слово, тогда заменить его на другую подстроку. Собственно вопрос: можно ли это сделать в haskell? Сейчас первое решено извлечением из текста Maybe String соответствующего правильной строке, а затем извлечением из неё правильной подстроки, а второе — не решено вообще.

★★★★★

Хм, биндинги к PCRE, причем много всяких, есть даже с квазиквотером.

А так, если тебе не сильно важна производительность, заюзай Parsec. Это намного приятнее, чем кошка-по-клаве-стайл регулярных выражений. И контекстно-зависимо можно сделать, отпять же...

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

Это я уже видел. Тут дело в другом. Допустим у меня есть кусок текста

Год 2011ый
Число 42

из которого мне необходимо извлечь год. Я могу воспользоваться perl и сделать как-то так:

$str =~ /^Год +([0-9]+)ый$/
И поимею в $1 выражение в скобочках. В haskell же у меня получается пока только выделить всю совпавшую строку из-за чего мне приходится разбирать её два раза (сначала ищу правильную строку, потом извлекаю из неё дату). Собственно меня интересует, есть ли возможность получить не всю совпавшую строку, а только её часть.

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

Parsec безусловно прекрасен, да и не факт что медленнее чем Text.Regex.Posix. Я когда в нём малость разобрался, поплакал о том что года 3 назад писал парсер для cue-таблиц на перловых регулярках. Но я как раз только что отказался от использования parsec'а по нескольким причинам: программка маленькая и парсер на parsec'е ощутимо раздувает её код, программка маленькая и парсер на parsec'е ощутимо раздувает бинарник, ну и использовать parsec для таких бытовых задач как-то странно.

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

Собственно меня интересует, есть ли возможность получить не всю совпавшую строку, а только её часть.

Prelude Text.Read Text.ParserCombinators.ReadP Data.Char> let p =  string "Year" >> skipSpaces >> (many1 $ satisfy isDigit) >>= \x -> (string "suf") >> return x in readP_to_S p "Year 2011suf"
[("2011","")]

Ну или записать с помощью do:

p = do { string "Year"
       ; skipSpaces
       ; x <- many1 $ satisfy isDigit
       ; string "suf"
       ; return x
       }

Вроде ничего не раздувается

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

Там совсем маленький инструмент меньше чем на сто строк включая сигнатуры, импорты и комментарии. И я очень надеюсь, что так оно и останется. Да и вопрос в общем был именно про то можно ли это решить при помощи регулярок. Text.ParserCombinators.ReadP в любом случае дома посмотрю.

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

Ну так я тебе дал вариант из 2ух строк импорта и ещё пары строк на всё остальное. Куда меньше-то?

anonymous
()
Ответ на: комментарий от KblCb

> Да и вопрос в общем был именно про то можно ли это решить при помощи регулярок.

оффтопик: если ты построчно обрабатываешь текст и тебе нужны регэкспы и удобна работа с ними, то советую делать это с помощью awk :)

anonymous
()

Если ничего не помогает, прочтите, наконец, доку

h> "abbbbcc" =~ "(a+)(b+)(c+)" :: [[String]]
[["abbbbcc","a","bbbb","cc"]]
lelf
()
Ответ на: комментарий от anonymous

Угу, и дёргать его из bash'е скрипта.

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

Чёрт. То что надо. В своё оправдание могу сказать лишь то, что с документацией в hackage обычно плохо. А почему такой странный тип?

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