Итак, я пишу код для синтаксического анализа и выражения IP-адреса и превращаю его в регулярное выражение, которое можно использовать для строки IP-адреса и возвращать логический ответ. Я написал код на C # (OO), и это было 110 строк кода. Я пытаюсь сравнить объем кода и выразительность C # с F # (я программист C # и нуб в F #). Я не хочу публиковать C # и F # только потому, что не хочу загромождать пост. При необходимости я сделаю это.
Во всяком случае, я приведу пример. Вот выражение:
192.168.0.250,244-248,108,51,7; 127.0.0.1
Я хотел бы взять это и превратить в следующее регулярное выражение:
((192 \ .168 \ .0 \ (250 |. 244 | 245 | 246 | 247 | 248 | 108 | 51 | 7)) | (127 \ 0,0 \ 0,0 \ 0,1))
Вот несколько шагов, которым я следую:
Операции:
Пробел на ";" 192.168.0.250,244-248,108,51,7 127.0.0.1
Пробел на "." 192 168 0 250 244-248,108,51,7
Break by "," 250 244-248 108 51 7
Перерыв на "-" 244 248
Я придумал F #, который производит вывод. Я пытаюсь перенаправить все операции, перечисленные выше, так как думаю, что это будет более выразительным. Кто-нибудь может сделать этот код лучше? Научи меня чему-нибудь:)
open System
let createItemArray (group:bool) (y:char) (items:string[]) =
[|
let indexes = items.Length - 1
let group = indexes > 0 && group
if group then
yield "("
for i in 0 .. indexes do
yield items.[i].ToString()
if i < indexes then
yield y.ToString()
if group then
yield ")"
|]
let breakBy (group:bool) (x:string) (y:char): string[] =
x.Split(y)
|> createItemArray group y
let breakItem (x:string) (y:char): string[] = breakBy false x y
let breakGroup (x:string) (y:char): string[] = breakBy true x y
let AddressExpression address:string =
let builder = new System.Text.StringBuilder "("
breakGroup address ';'
|> Array.collect (fun octet -> breakItem octet '.')
|> Array.collect (fun options -> breakGroup options ',')
|> Array.collect (fun (ranges : string) ->
match (breakGroup ranges '-') with
| x when x.Length > 3
-> match (Int32.TryParse(x.[1]), Int32.TryParse(x.[3])) with
| ((true, a) ,(true, b))
-> [|a .. b|]
|> Array.map (int >> string)
|> createItemArray false '-'
| _ -> [|ranges|]
| _ -> [|ranges|]
)
|> Array.iter (fun item ->
match item with
| ";" -> builder.Append ")|("
| "." -> builder.Append "\."
| "," | "-" -> builder.Append "|"
| _ -> builder.Append item
|> ignore
)
builder.Append(")").ToString()
let address = "192.168.0.250,244-248,108,51,7;127.0.0.1"
AddressExpression address