String 比较字符串结构
我正在F#的一个项目中工作,我希望找到一种方法来确定两个字符串是否具有相同的结构。我知道有一些算法(比如Levenshtein距离)可以提供类似字符串在内容方面的近似值,但我更感兴趣的是比较字符串的实际结构。在结构与内容方面,考虑下面的例子: 根据Levenshtein距离等算法,“2015年7月14日”和“1999年11月6日”将被归类为非常不同的类别。然而,它们在结构上是相同的(日期) 此外,理想情况下,以三个字母(“USA123”、“USA456”、“USA789”)开头的一组字符串与其他六个字符串(如“123123”或“USAUSA”)具有不同的结构String 比较字符串结构,string,algorithm,f#,fparsec,String,Algorithm,F#,Fparsec,我正在F#的一个项目中工作,我希望找到一种方法来确定两个字符串是否具有相同的结构。我知道有一些算法(比如Levenshtein距离)可以提供类似字符串在内容方面的近似值,但我更感兴趣的是比较字符串的实际结构。在结构与内容方面,考虑下面的例子: 根据Levenshtein距离等算法,“2015年7月14日”和“1999年11月6日”将被归类为非常不同的类别。然而,它们在结构上是相同的(日期) 此外,理想情况下,以三个字母(“USA123”、“USA456”、“USA789”)开头的一组字符串与其他
我意识到这很可能是一个相当复杂的解决方案,但我想知道是否存在类似的问题,我错过了它,或者是否有人对此有任何想法/想法。虽然不是完整的答案,但您可以做一些非常基本的测试,以捕捉您上面给出的示例:
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