我发现这篇关于使用正则表达式的活动模式的有用文章:http: //www.markhneedham.com/blog/2009/05/10/f-regular-expressionsactive-patterns/
文章中使用的原始代码片段是这样的:
open System.Text.RegularExpressions
let (|Match|_|) pattern input =
let m = Regex.Match(input, pattern) in
if m.Success then Some (List.tl [ for g in m.Groups -> g.Value ]) else None
let ContainsUrl value =
match value with
| Match "(http:\/\/\S+)" result -> Some(result.Head)
| _ -> None
这会让您知道是否找到了至少一个 url 以及该 url 是什么(如果我正确理解了该片段)
然后在评论部分乔尔提出了这个修改:
另一种选择,因为给定的组可能是也可能不是成功的匹配:
List.tail [ for g in m.Groups -> if g.Success then Some g.Value else None ]
或者,也许您为您的组提供标签,并且您想按名称访问它们:
(re.GetGroupNames() |> Seq.map (fun n -> (n, m.Groups.[n])) |> Seq.filter (fun (n, g) -> g.Success) |> Seq.map (fun (n, g) -> (n, g.Value)) |> Map.ofSeq)
在尝试结合所有这些之后,我想出了以下代码:
let testString = "http://www.bob.com http://www.b.com http://www.bob.com http://www.bill.com"
let (|Match|_|) pattern input =
let re = new Regex(pattern)
let m = re.Match(input) in
if m.Success then Some ((re.GetGroupNames()
|> Seq.map (fun n -> (n, m.Groups.[n]))
|> Seq.filter (fun (n, g) -> g.Success)
|> Seq.map (fun (n, g) -> (n, g.Value))
|> Map.ofSeq)) else None
let GroupMatches stringToSearch =
match stringToSearch with
| Match "(http:\/\/\S+)" result -> printfn "%A" result
| _ -> ()
GroupMatches testString;;
当我在交互式会话中运行代码时,输出如下:
map [("0", "http://www.bob.com"); ("1", "http://www.bob.com")]
我试图达到的结果看起来像这样:
map [("http://www.bob.com", 2); ("http://www.b.com", 1); ("http://www.bill.com", 1);]
基本上是找到的每个唯一匹配的映射,然后是在文本中找到特定匹配字符串的次数的计数。
如果您认为我在这里走错了路,请随时提出完全不同的方法。我对活动模式和正则表达式都有点陌生,所以我什至不知道从哪里开始尝试解决这个问题。
我也想出了这个,这基本上就是我在 C# 中翻译成 F# 时所做的。
let testString = "http://www.bob.com http://www.b.com http://www.bob.com http://www.bill.com"
let matches =
let matchDictionary = new Dictionary<string,int>()
for mtch in (Regex.Matches(testString, "(http:\/\/\S+)")) do
for m in mtch.Captures do
if(matchDictionary.ContainsKey(m.Value)) then
matchDictionary.Item(m.Value) <- matchDictionary.Item(m.Value) + 1
else
matchDictionary.Add(m.Value, 1)
matchDictionary
运行时返回:
val matches : Dictionary = dict [("http://www.bob.com", 2); ("http://www.b.com", 1); ("http://www.bill.com", 1)]
这基本上是我正在寻找的结果,但我正在尝试学习执行此操作的功能方式,我认为这应该包括活动模式。如果它比我的第一次尝试更有意义,请随意尝试“功能化”它。
提前致谢,
鲍勃