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是什么(如果我正确地理解了代码片段)。
然后,在评论部分,Joel建议进行以下修改:
尝试将所有内容结合在一起后,我得到了以下代码:Alternative, since a given group may or may not be a successful match:
List.tail [ for g in m.Groups -> if g.Success then Some g.Value else None ]
Or maybe you give labels to your groups and you want to access them by name:
(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);]
基本上是对每个唯一匹配项进行映射,然后计算在文本中找到该特定匹配字符串的次数。
如果您认为我走了错误的道路,请随时建议完全不同的方法。我对Active Patterns和正则表达式都比较新,所以我甚至不知道从哪里开始修复它。
我还想到了这个,基本上是我在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)]
这基本上是我想要的结果,但我正在尝试学习函数式方法来完成此操作,我认为这应该包括活动模式。如果将其“功能化”比我的第一次尝试更有意义,请随意尝试。
提前感谢,
鲍勃
CompiledMatch
活动模式每次应用时都会编译正则表达式... 因此大多数情况下性能实际上会适得其反... - Mauricio SchefferCompiledMatch
使用静态方法Regex.Match
,因此在幕后创建的Regex
实例被缓存,2)RegexOptions.Compiled
标志用于构建(仅创建一次并缓存)Regex
实例,而不是每个匹配。因此,对于每个与CompiledMatch
一起使用的唯一正则表达式模式,只会创建一个已编译的正则表达式,该正则表达式在第一次调用后被缓存以供后续调用使用。 - Stephen Swensen