String 比较字符串结构

String 比较字符串结构,string,algorithm,f#,fparsec,String,Algorithm,F#,Fparsec,我正在F#的一个项目中工作,我希望找到一种方法来确定两个字符串是否具有相同的结构。我知道有一些算法(比如Levenshtein距离)可以提供类似字符串在内容方面的近似值,但我更感兴趣的是比较字符串的实际结构。在结构与内容方面,考虑下面的例子: 根据Levenshtein距离等算法,“2015年7月14日”和“1999年11月6日”将被归类为非常不同的类别。然而,它们在结构上是相同的(日期) 此外,理想情况下,以三个字母(“USA123”、“USA456”、“USA789”)开头的一组字符串与其他

我正在F#的一个项目中工作,我希望找到一种方法来确定两个字符串是否具有相同的结构。我知道有一些算法(比如Levenshtein距离)可以提供类似字符串在内容方面的近似值,但我更感兴趣的是比较字符串的实际结构。在结构与内容方面,考虑下面的例子:

根据Levenshtein距离等算法,“2015年7月14日”和“1999年11月6日”将被归类为非常不同的类别。然而,它们在结构上是相同的(日期)

此外,理想情况下,以三个字母(“USA123”、“USA456”、“USA789”)开头的一组字符串与其他六个字符串(如“123123”或“USAUSA”)具有不同的结构


我意识到这很可能是一个相当复杂的解决方案,但我想知道是否存在类似的问题,我错过了它,或者是否有人对此有任何想法/想法。

虽然不是完整的答案,但您可以做一些非常基本的测试,以捕捉您上面给出的示例:

  • 准备字符类型列表。我的意思是区分大写、小写、数字、分隔符等
  • 比较两个字符串时,请检查同一位置的字符是否属于同一组。这将为您提供
    19/07/1983
    25/12/1853
    相似,但
    19/07/1983
    25/12/185A
    不相似。与
    USAUSA
    USA123
    相同

  • 要使标识更加精确,需要创建越来越多的精确组。

    正如前面所建议的,您需要对字符进行分类。完成后,比较两组字符分类就很容易了。这是一个F#样本:


    这个问题看起来有点主观,因为它需要基于意见的答案,其中许多答案可能同样好。让我试着回答,但同样,这可能对你的特定目的有好处,也可能没有好处

    如果您的应用程序只是一个用于自学的小项目,那么一系列简单的正则表达式就可以了,只要您将它们合并到一系列尝试中

    如果项目很大,并且预计会以某种方式增长(例如,可能会出现新的字符串格式),那么我会推荐一些解析器组合器库,比如它非常适合解析复杂字符串。这里还有一个标签

    使用combinator,您可以开发单独的解析器,并在需要时将它们组合在一起,如下所示:

    // Domain specifics
    type MyData =
        | Date of DateTime
        | CountryCode of (string * code)
        | Error
    
    // Parsers
    let parseDate: Parser<MyData> =
        ... // something returning MyData.Date(x)
    let parseCountryCode: Parser<MyData> =
        ... // something returning MyData.CountryCode(x, y)
    
    // a simple combined parser
    let parseRoot: Parser<MyData> =
        [parseDate; parseCountryCode; parseSomethingElse;]
        |> choice
    
    let myCode stringTroParse =
        let foundValue =
            match runParserOnString parseRoot myUserState myStreamName stringTroParse with
            | Success(result, _, _) -> result
            | Failure(_, _, _)      -> MyData.Error
        // here you can work with foundValue as usual
    
    //域详细信息
    类型MyData=
    |日期时间
    |国家代码(字符串*代码)
    |错误
    //解析器
    让parseDate:解析器=
    ... // 返回MyData.Date(x)的内容
    让parseCountryCode:解析器=
    ... // 返回MyData.CountryCode(x,y)的内容
    //一种简单的组合解析器
    让parseRoot:Parser=
    [parseDate;parseCountryCode;parseSomethingElse;]
    |>选择
    让丝状霉=
    让我们来看看价值=
    将runParserOnString ParserRoot myUserState myStreamName StringtParse与匹配
    |成功(结果)->result
    |失败(u,u,u)->MyData.Error
    //在这里,您可以像往常一样使用foundValue
    
    使用这种方法,比较几个字符串的结构变得很简单:它们被解析为
    MyData
    discriminatedunion的不同情况


    如果偶尔需要一个新的解析器,您可以在顶部添加另一个函数,并将其引用添加到
    parseRoot
    body中。此外,如果需要更复杂的东西(例如,您需要一些保护规则或不同的组合解析器的方法),库允许您这样做。

    是的,这听起来像是人工智能问题,而不是算法问题。当然不是语言问题。
    // Domain specifics
    type MyData =
        | Date of DateTime
        | CountryCode of (string * code)
        | Error
    
    // Parsers
    let parseDate: Parser<MyData> =
        ... // something returning MyData.Date(x)
    let parseCountryCode: Parser<MyData> =
        ... // something returning MyData.CountryCode(x, y)
    
    // a simple combined parser
    let parseRoot: Parser<MyData> =
        [parseDate; parseCountryCode; parseSomethingElse;]
        |> choice
    
    let myCode stringTroParse =
        let foundValue =
            match runParserOnString parseRoot myUserState myStreamName stringTroParse with
            | Success(result, _, _) -> result
            | Failure(_, _, _)      -> MyData.Error
        // here you can work with foundValue as usual