Куча говна / Говнокод #13674 Ссылка на оригинал

0

  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  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 bormand, (Updated )

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

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

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

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

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

      Правильная формулировка вопроса: нахрена проверять диапазоны регулярками?.
      Ответить

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

Семь раз отмерь — один отрежь, guest!

    А не использовать ли нам bbcode?


    8