- 01
- 02
- 03
- 04
- 05
- 06
- 07
- 08
- 09
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 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
kegdan 27.08.2013 11:32 # +1
по идеи нужно сделать функцию ->
вход - 2 числа - выход -строка регеспа, так?
bormand 27.08.2013 11:36 # +1
3 числа. Еще система счисления передается, чтобы шестнадцатеричные и восьмиричные можно было мутить ;)
kegdan 27.08.2013 11:52 # 0
bormand 27.08.2013 12:09 # +1
kegdan 27.08.2013 12:15 # 0
kegdan 27.08.2013 12:17 # 0
без использования строк )))
bormand 27.08.2013 12:24 # +3
А зачем там строки? Массива символов вполне достаточно.
kegdan 27.08.2013 12:41 # 0
я имел в виду не переводя в символы и строки
3Doomer 27.08.2013 15:47 # +1
Yuuri 28.08.2013 12:35 # +1
Ещё по мелочи, что бросилось:
> digit d = chr (ord '0' + fromIntegral d) <...>
Data.Char.intToDigit
> "[" ++ rangeToStr (digit min) (digit max) ++ "]" <...>
Text.Printf
Остального пока не уразумею :(
bormand 28.08.2013 13:42 # 0
Да, тогда будет почитабельней.
> копошения с подстроками
На любом языке можно писать как на PHP.
guest 27.08.2013 11:46 # 0
PS: Используй манды.
3Doomer 27.08.2013 15:47 # +2
kegdan 27.08.2013 16:02 # 0
Lure Of Chaos 28.08.2013 00:18 # 0
bormand 28.08.2013 06:36 # 0
Правильная формулировка вопроса: нахрена проверять диапазоны регулярками?.
anonimb84a2f6fd141 28.08.2013 02:29 # 0
Это действительно так читается?
kegdan 28.08.2013 14:44 # 0
нажми на кнопку послушать и узнаешь
anonimb84a2f6fd141 28.08.2013 15:54 # −1