1. Куча / Говнокод #13674

    +126

    1. 01
    2. 02
    3. 03
    4. 04
    5. 05
    6. 06
    7. 07
    8. 08
    9. 09
    10. 10
    11. 11
    12. 12
    13. 13
    14. 14
    15. 15
    16. 16
    17. 17
    18. 18
    19. 19
    20. 20
    21. 21
    22. 22
    23. 23
    24. 24
    25. 25
    26. 26
    27. 27
    28. 28
    29. 29
    30. 30
    31. 31
    32. 32
    33. 33
    34. 34
    35. 35
    36. 36
    37. 37
    38. 38
    39. 39
    40. 40
    41. 41
    42. 42
    43. 43
    44. 44
    45. 45
    46. 46
    47. 47
    48. 48
    49. 49
    50. 50
    51. 51
    52. 52
    53. 53
    54. 54
    55. 55
    56. 56
    57. 57
    58. 58
    59. 59
    import Data.Char
    import Data.List
    
    digitRangeToRegex :: Integer -> Integer -> String
    digitRangeToRegex min max
        | min == max = digit min : ""
    -- uncomment if you want \d instead of [0-9]
    --    | min == 0 && max == 9 = "\\d"
        | min >= 10 || max <= 9 = "[" ++ rangeToStr (digit min) (digit max) ++ "]"
        | otherwise = "[" ++ rangeToStr (digit min) '9' ++ rangeToStr 'a' (digit max) ++ "]"
        where
            rangeToStr min max
                | min == max = min : ""
                | otherwise = min : '-' : max : ""
            digit d
                | d >= 0 && d <= 9 = chr (ord '0' + fromIntegral d)
                | d < 36 = chr (ord 'a' + fromIntegral d - 10)
    
    numberRangeToRegex :: Integer -> Integer -> Integer -> String
    numberRangeToRegex base min max
        | min == 0 && max == 0 = "0"
        | cmin == cmax = intercalate "|" $ map formatRanges $ step dmin dmax
        | otherwise = intercalate "|" $
            (map formatRanges $ step dmin (replicate cmin (base-1))) ++
            (if cmin + 1 < cmax then [digitRangeToRegex 1 (base - 1) ++ digitRangeToRegex 0 (base-1) ++ formatCount cmin (cmax-2)] else []) ++
            (map formatRanges $ step (1 : replicate (cmax-1) 0) dmax)
        where
            digits 0 = [0]
            digits n = reverse $ map (`mod` base) $ takeWhile (>0) $ iterate (`div` base) n
            dmin = digits min
            dmax = digits max
            cmin = length dmin
            cmax = length dmax
            step [] [] = [[]]
            step (a:as) (b:bs) =
                if a == b then
                    prepend a $ step as bs
                else
                    (if zeroHead then [] else prepend a $ step as nines) ++
                    (if na > nb then [] else [(na, nb) : replicate (length as) (0, base-1)]) ++
                    (if nineTail then [] else prepend b $ step zeros bs)
                where
                    suffixLen = length as
                    zeroHead = all (== 0) as
                    nineTail = all (== base-1) bs
                    na = if zeroHead then a else a+1
                    nb = if nineTail then b else b-1
                    zeros = replicate suffixLen 0
                    nines = replicate suffixLen (base-1)
                    prepend x = map ((x, x):)
            formatRanges = concatMap formatGroup . group . dropWhile (== (0,0)) where
                formatGroup [(min, max)] = digitRangeToRegex min max
                formatGroup xs@((min, max) : _)
                    | min == max = concat $ replicate (length xs) $ digitRangeToRegex min max
                    | otherwise = digitRangeToRegex min max ++ "{" ++ show (length xs) ++ "}"
            formatCount min max
                | min == 1 && max == 1 = ""
                | min == max = "{" ++ show min ++ "}"
                | otherwise = "{" ++ show min ++ "," ++ show max ++ "}"

    Генератор реджексов, проверяющих диапазон чисел. Говнецо то еще, причем не только в реализации и выхлопе, но и в самой идее :)

    Пример: http://ideone.com/FzAmYd

    Запостил: bormand, 27 Августа 2013

    Комментарии (19) RSS

    • А теперь давайте думать как сделать это кошшерно
      по идеи нужно сделать функцию ->
      вход - 2 числа - выход -строка регеспа, так?
      Ответить
      • > вход - 2 числа - выход -строка регеспа, так?
        3 числа. Еще система счисления передается, чтобы шестнадцатеричные и восьмиричные можно было мутить ;)
        Ответить
        • мисье не ищет легких путей)
          Ответить
          • Ну в айпишниках же можно писать в 8-, 10- и 16-ричной системах. Отсюда и требования к функции. Да и функцию это совсем не усложняет ;)
            Ответить
            • Просто обрезается алфавит.
              Ответить
            • Вообще решать такую проблему регеспами - все равно, что решать http://govnokod.ru/3394
              без использования строк )))
              Ответить
              • > без использования строк
                А зачем там строки? Массива символов вполне достаточно.
                Ответить
                • ну так строка - это и есть массив символов. в некотором роде

                  я имел в виду не переводя в символы и строки
                  Ответить
      • Из глобальных улучшательств мне видится только возможность сначала сделать какой-нибудь ADT для регулярок, а потом его сериализовать, вместо копошения с подстроками.
        Ещё по мелочи, что бросилось:
        > digit d = chr (ord '0' + fromIntegral d) <...>
        Data.Char.intToDigit
        > "[" ++ rangeToStr (digit min) (digit max) ++ "]" <...>
        Text.Printf
        Остального пока не уразумею :(
        Ответить
        • > возможность сначала сделать какой-нибудь ADT для регулярок, а потом его сериализовать, вместо копошения с подстроками
          Да, тогда будет почитабельней.

          > копошения с подстроками
          На любом языке можно писать как на PHP.
          Ответить
    • Опа говно. Много говна. На хаскеле? Тогда нет. Значит это гигантское количество говна. На Хаскеле все программы маленькие.

      PS: Используй манды.
      Ответить
    • а зачем генерировать регулярки?
      Ответить
      • Ну не писать же это говно для проверки диапазонов руками ;)

        Правильная формулировка вопроса: нахрена проверять диапазоны регулярками?.
        Ответить
    • > реджексов
      Это действительно так читается?
      Ответить
      • https://translate.google.ru/?q=regular+expressions&um=1&ie=UTF-8&hl=ru&sa=N&tab=wT

        нажми на кнопку послушать и узнаешь
        Ответить

    Добавить комментарий