我正在研究F#中的一个项目,我希望能够找到一种方法来识别两个字符串是否具有相同的结构。我知道有些算法(比如Levenshtein Distance)提供了类似字符串在内容方面的近似值,但我更感兴趣的是比较字符串的实际结构。在结构与内容方面,请考虑以下示例:
&#34 07 /二千零十五分之十四"和" 11/06 / 1999"根据像Levenshtein Distance这样的算法,它将被归类为非常不同的。但是,它们在结构上都是相同的(日期)。
此外,一组以三个字母开头的字符串(" USA123"," USA456"," USA789")理想情况下会识别为与其他六个字符串不同的结构,如" 123123"或" USAUSA"。
我意识到这很可能是一个相当复杂的解决方案,但我想知道是否存在这样的事情并且我错过了,或者是否有人对此事有任何想法/想法。
答案 0 :(得分:1)
虽然不是一个完整的答案,但你可以做一些非常基本的测试来捕捉上面给出的例子:
19/07/1983
和25/12/1853
相似,但19/07/1983
和25/12/185A
不相似。与USAUSA
和USA123
相同。使识别更准确是一个创建越来越精确的群体的问题......
答案 1 :(得分:0)
如上所述,您需要对角色进行分类。完成后,比较两组字符分类很容易。这是一个F#样本:
let areStructurallyEqual (a, b) =
let charClass= function
| c when Char.IsLetter(c) -> 'L'
| c when Char.IsDigit(c) -> 'D'
| c when Char.IsSymbol(c) -> 'S'
| c when Char.IsWhiteSpace(c) -> ' '
| _ -> '_'
let structureString i = new String (i |> Seq.map charClass |> Seq.toArray)
structureString a = structureString b
[( "07/14/2015", "11/06/1999" ); ("USA123", "USA456"); ("123123", "USA123");]
|> Seq.map areStructurallyEqual
// returns [ True; True; False; ]
答案 2 :(得分:0)
这个问题看起来有点主观,因为它邀请基于意见的答案,其中许多可能同样好。让我尝试回答,但同样,它可能会或可能不会对您的特定目的有益。
如果您的应用程序只是一个用于自学的小项目,那么一系列简单的正则表达式可能没问题,前提是您将它们合并为一系列尝试。
如果项目很大并且应该以某种方式增长(例如,可能会出现新的字符串格式),那么我会推荐一些解析器组合库,例如FParsec,它非常适合解析复杂字符串。这里还有一个fparsec标记。
使用组合器,您可以开发各自的解析器并将它们组合在一起,但需要这样:
// 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
区分联合的不同情况。
如果偶尔需要新的解析器,您可以在顶部添加另一个函数并将其引用添加到parseRoot
正文中。此外,如果需要更复杂的东西(例如,您需要一些防护规则或不同的方法来组合解析器),则可以使用该库。