Regex .NET正则表达式,用于后跟一些逗号分隔数字的指令

Regex .NET正则表达式,用于后跟一些逗号分隔数字的指令,regex,f#,capture,comma,directive,Regex,F#,Capture,Comma,Directive,我正在尝试用F#编写一个正则表达式,它将匹配这样的东西 .float -.05, 2.4 .float 31.1234 .float -0.5, 1.0, 1.1 let matchFloat input = let matches = Regex(@"(\.float )?(?<float>[+-]?\d*\.\d+)").Matches(input) ([for m in matches -> m.Groups.["float"].Value, match

我正在尝试用F#编写一个正则表达式,它将匹配这样的东西

.float -.05, 2.4
.float 31.1234
.float -0.5, 1.0, 1.1
let matchFloat input =
    let matches = Regex(@"(\.float )?(?<float>[+-]?\d*\.\d+)").Matches(input)
    ([for m in matches -> m.Groups.["float"].Value, matches.Count > 0)
我正在尝试这样的事情

.float -.05, 2.4
.float 31.1234
.float -0.5, 1.0, 1.1
let matchFloat input =
    let matches = Regex(@"(\.float )?(?<float>[+-]?\d*\.\d+)").Matches(input)
    ([for m in matches -> m.Groups.["float"].Value, matches.Count > 0)
让matchFloat输入=
让matches=Regex(@“(\.float)?(?[+-]?\d*\.\d+)。匹配(输入)
([对于匹配中的m->m.Groups.[“float”].Value,matches.Count>0)
哪种类型有效,但我有相同的东西。double,无论我的匹配表达式中的第一个是什么,都将是匹配的-因为我做了一个“发生0或1次”,这意味着遵循任一指令的浮点数字符串将被视为相同的

那么,我如何确保.float存在,而无需执行input.StartsWith(…)?我知道有一种方法可以编写此正则表达式,以便它与m.Groups。[“float”].值将只返回我需要的值,而不必在事后删除空格或逗号

我已经玩了好几个小时了,就是不能让它做我想做的事情。我尝试过使用“向后看/向前看”和其他一些东西,但没有运气


请帮帮我!:)

好吧,这会让你在去医院的路上感觉很好

您可以使用正查找与交替相结合的方法,将行开头的
.float
.decimal
捕获到一个组中,然后检查捕获的是哪一个。查找本身不参与主要捕获,因此数字仍然是“组0”中唯一的内容

然后是我最喜欢的技巧-通过在lookback中添加一个
*
(在
float
decimal
之后),您可以成功地从输入字符串返回多个匹配项,每个匹配项共享初始的
.float
.decimal
,但每个匹配项都向前缩放以捕获不同的数字集

在其上放置一个带有小DU类型的弓,以代表两种情况:

type DataPoint =
    | Float of string
    | Decimal of string

let parse input =
    let patt = "(?<=^\.((float)|(decimal)).*(,?\s+))[+-]?\d*\.\d+(?=\s*(,|$))"
    Regex.Matches(input, patt)
    |> Seq.cast<Match>
    |> Seq.map (fun m ->
        match (m.Groups.[2].Success, m.Groups.[3].Success) with
        | (true, false) -> Float(m.Value)
        | (false, true) -> Decimal(m.Value)
        | _ -> failwith "??")
    |> List.ofSeq

// positive cases
parse ".float -.05, 2.4"        // [Float "-.05"; Float "2.4"]
parse ".float 31.1234"          // [Float "31.1234"]
parse ".float -0.5, 1.0, 1.1"   // [Float "-0.5"; Float "1.0"; Float "1.1"]
parse ".decimal 123.456, -22.0" // [Decimal "123.456"; Decimal "-22.0"]

// negative cases, plucks out valid bits
parse ".decimal xyz,,.., +1.0, .2.3.4, -.2 "  // [Decimal "+1.0"; Decimal "-.2"]
parse ".float 1.0, 2.0-, 3."                  // [Float "1.0"]
类型数据点=
|弦的浮动
|字符串小数
让我们分析输入=

让patt=“(?好吧,这会让你在去学校的路上走得很好

您可以使用正查找与交替相结合的方法,将行开头的
.float
.decimal
捕获到一个组中,然后检查捕获的是哪一个。查找本身不参与主要捕获,因此数字仍然是“组0”中唯一的内容

然后是我最喜欢的技巧-通过在lookback中添加一个
*
(在
float
decimal
之后),您可以成功地从输入字符串返回多个匹配项,每个匹配项共享初始的
.float
.decimal
,但每个匹配项都向前缩放以捕获不同的数字集

在其上放置一个带有小DU类型的弓,以代表两种情况:

type DataPoint =
    | Float of string
    | Decimal of string

let parse input =
    let patt = "(?<=^\.((float)|(decimal)).*(,?\s+))[+-]?\d*\.\d+(?=\s*(,|$))"
    Regex.Matches(input, patt)
    |> Seq.cast<Match>
    |> Seq.map (fun m ->
        match (m.Groups.[2].Success, m.Groups.[3].Success) with
        | (true, false) -> Float(m.Value)
        | (false, true) -> Decimal(m.Value)
        | _ -> failwith "??")
    |> List.ofSeq

// positive cases
parse ".float -.05, 2.4"        // [Float "-.05"; Float "2.4"]
parse ".float 31.1234"          // [Float "31.1234"]
parse ".float -0.5, 1.0, 1.1"   // [Float "-0.5"; Float "1.0"; Float "1.1"]
parse ".decimal 123.456, -22.0" // [Decimal "123.456"; Decimal "-22.0"]

// negative cases, plucks out valid bits
parse ".decimal xyz,,.., +1.0, .2.3.4, -.2 "  // [Decimal "+1.0"; Decimal "-.2"]
parse ".float 1.0, 2.0-, 3."                  // [Float "1.0"]
类型数据点=
|弦的浮动
|字符串小数
让我们分析输入=

让patt=“(?试试这个
\.浮点[+-]?[0-9\,]+
也参考这个()

试试这个
\.浮点[+-]?[0-9\,]+
也参考这个()

实际上,我看不出在这种情况下Regex有什么用处。使用字符串函数和系统解析函数更具可读性和类型安全性,可以解析输入。借用@latkin答案中的数据点:

open System

type DataPoint =
    | Float of float
    | Decimal of decimal

let listparse parser mapper = 
    List.choose (fun f -> match parser f with true, v -> Some (mapper v) | _ -> None)

let parse (input: string) =
    match Array.toList (input.Split([|',';' '|])) with
    | ".float"::rest -> rest |> listparse Double.TryParse Float
    | ".decimal"::rest -> rest |> listparse Decimal.TryParse Decimal
    | _ -> []

使用.TryParse()方法中的额外参数,您可以轻松处理更复杂的浮点输入格式,如指数表示法(例如1.3E5)

实际上,我看不出在这种情况下Regex有什么用处。使用字符串函数和系统解析函数更具可读性和类型安全性,可以解析输入。借用@latkin答案中的数据点:

open System

type DataPoint =
    | Float of float
    | Decimal of decimal

let listparse parser mapper = 
    List.choose (fun f -> match parser f with true, v -> Some (mapper v) | _ -> None)

let parse (input: string) =
    match Array.toList (input.Split([|',';' '|])) with
    | ".float"::rest -> rest |> listparse Double.TryParse Float
    | ".decimal"::rest -> rest |> listparse Decimal.TryParse Decimal
    | _ -> []

使用.TryParse()方法中的额外参数,您可以轻松处理更复杂的浮点输入格式,如指数表示法(例如1.3E5)

那么它应该匹配.float之后的第一对数字还是所有数字?它应该匹配所有数字和。float是必须出现的?是的-我还需要.double,我需要能够区分它们。为什么输入.StartsWith(…)这是一个糟糕的解决方案吗?它肯定更具可读性且更易于实现。那么它应该匹配.float之后的第一对数字还是所有数字?它应该匹配所有的数字和。float是必须出现的?是-我也会有.double,我需要能够区分它们。为什么输入.StartsWith(…)这是一个糟糕的解决方案吗?它肯定更具可读性且更易于实现。这有几个问题:1.它匹配伪字符串,如
.float,,,,,
.float 5.4.3.,.0
等。2.它不能捕获整个有效字符串,如
.float 1.5,-2.5
3。它无法提取单个数字组,如操作所示明确了目标。这有几个问题:1.它匹配伪字符串,如
.float、、、
.float 5.4.3、.0
等。2.它不能捕获整个有效字符串,如
.float 1.5、-2.5
3。它无法提取单个数字组,正如OP明确指出的那样。实际上,您的注册表ex还匹配“.float 5.4.3.”、.0”等字符串,这是极好的反馈,完全正确!更新传入。实际上,您的正则表达式还匹配“.float 5.4.3.”、.0”等字符串,这是极好的反馈,完全正确!更新传入。