2014-09-12 124 views
-3

我是C#的新手,所以我没有太多经验。C#查找基于输入字符串的子字符串

对于一个简单的体验项目,我需要从一个类似于我得到的输入的句子中找到关键字。

现在看来解决方案比我想象的要复杂得多,所以请原谅我缺乏经验或知识。

我从我的数据库中得到一个字符串,它可以有任意数量的字母,其余的字符串都是数字,但字符串中的字符总数必须用于匹配。

string ThisIsTheTemplateToLookFor = "AB12345678" 

而且我有一些文本字符串:

string FromThisStringINeedToFind = "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s and here comes the text to find AB54925871"; 

随着ThisIsTheTemplateToLookFor可能是一个正则表达式的命令必须建立查找文本的类似作品。

所以它需要找到:

AB12345678 
AB87654321 
AB67812345 
... 
etc 
... 

正则表达式必须寻找这两个字母,并从样本串8个的数字。 或在不同的情况ThisIsTheTemplateToLookFor字符串可以为A1234正则表达式应该找到A1234A4321A3910

或者蒂姆Schmelter建议也许Levenshtein距离算法

对不起,因为我的语言不是说英语的本地人

我认为他的观点是,搜索字符串在细微方面与尚未枚举的方式不同,而不是应该找到的字符串。在该示例中,搜索字符串是AB12345678,但应该发现的字符串是AB54925871

我的猜测是,如果搜索字符串是AB12345678,那么应该找到包含任意顺序的10个字符的任何10个字符的子字符串。 - 斧

  • 在第一个例子AB和任何8位数字应该给出结果。
  • 在第二个例子A和任何4个数字应该给出结果。
+0

而不是问一个新的问题,你应该编辑[你的旧](http://stackoverflow.com/questions/25815680/use-a-string-to-find-a-simular-out-of-a -large-string-with-regex),以便它重新打开。 – 2014-09-12 22:04:11

+0

谨慎澄清?我不明白你在问什么......为你的程序提供更多的输入和输出样本。 – Andre 2014-09-12 22:04:12

+0

嗨@Tim,我不知道如何,你的回应已被删除,所以我有点卡在这里。 – Giancarlo 2014-09-12 22:05:55

回答

0

由于您已经明确了your first question中的要求,但由于它仍然关闭,我无法发布答案,因此我会在这里放置我的两分钱。

你不需要这样的正则表达式,下面的工作按需要。您的样品:

string sample = "AB12345678"; 
string subject = "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s and here comes the text to find AB54925871"; 

现在要找到句子中的词同Length,这与相同的字母开始,并以相同数量的(连续)数字结尾:

string letters = string.Join("", sample.TakeWhile(Char.IsLetter)); 
int countDigits = sample.SkipWhile(Char.IsLetter).TakeWhile(Char.IsDigit).Count(); 

你可以使用这个LINQ查询:

var matchingWords = subject.Split() // splits by spaces, tabs and new-lines 
    .Where(word => sample.Length == word.Length 
     && letters == string.Join("", word.TakeWhile(Char.IsLetter)) 
     && countDigits == word.SkipWhile(Char.IsLetter).TakeWhile(Char.IsDigit).Count()); 
string word = matchingWords.FirstOrDefault(); // AB54925871 

如果没有匹配的词被找到返回null

如果你想找到的所有,并与逗号分隔:

string allWords = string.Join(",", matchingWords); 
+0

非常感谢您的回答,我试过您的解决方案。 它就像一个魅力。 但是我在测试过程中发现了一些新情况: 可能会发现可以找到多个样本。 我将如何让“var matchingWords”在由“,”分隔的列表中具有所有命中。 或者我需要为此创建一个新问题? – Giancarlo 2014-09-13 08:14:59

+0

嗨@Tim,我无法接受你的答案两次,但非常感谢你,因为你的回答帮了我很多,以通过这个问题。 – Giancarlo 2014-09-13 10:40:34

0

从您的问题声明,我们不是在这里谈论火箭科学:只要创建一个这样的小工厂方法,做什么你想:

static Regex CreateRegularExpressionFromTemplate(string template) 
{ 
    StringBuilder sb = new StringBuilder() ; 

    foreach(char c in template) 
    { 
    if  (char.IsLetter(  c)) sb.Append(@"\p{L}") ; 
    else if (char.IsNumber(  c)) sb.Append(@"\d" ) ; 
    else if (char.IsWhiteSpace( c)) sb.Append(@"\s" ) ; 
    else if (char.IsPunctuation(c)) sb.Append(@"\p{P}") ; 
    else throw new ArgumentOutOfRangeException("template") ; 
    } 

    string pattern = sb.ToString() ; 
    Regex rx = new Regex(pattern) ; 
    return rx ; 
} 

这将关闭此

@"AB12345678" 

这个

@"\p{L}\p{L}\d\d\d\d\d\d\d\d" 

然后你就可以像

Regex rx = CreateRegularExpressionFromTemplate("AB12345678") ; 
Match m = rx.Match("This is zX98320987 speaking.") ; 

if (m.Success) 
{ 
    Console.WriteLine("We matched '{0}'" , m.Value) ; 
} 
else 
{ 
    Console.WriteLine("no match found") ; 
} 

的东西,并获得预期

We matched 'zX98320987' 

编辑以注:如果你需要匹配一个字边界,您可以简单地添加适当的正面后视和积极的前瞻断言:

static Regex CreateRegularExpressionFromTemplate(string template) 
{ 
    StringBuilder sb = new StringBuilder() ; 

    sb.Append(@"(?<=(^|\W))") ; // require the match to at the beginning of a word 
    foreach(char c in template) 
    { 
    if  (char.IsLetter(  c)) sb.Append(@"\p{L}") ; 
    else if (char.IsNumber(  c)) sb.Append(@"\d" ) ; 
    else if (char.IsWhiteSpace( c)) sb.Append(@"\s" ) ; 
    else if (char.IsPunctuation(c)) sb.Append(@"\p{P}") ; 
    else throw new ArgumentOutOfRangeException("template") ; 
    } 
    sb.Append(@"(?=($|\W))" ; // require the match to end at the end of a word 

    string pattern = sb.ToString() ; 
    Regex rx = new Regex(pattern) ; 
    return rx ; 
} 
+0

感谢您的回答,但首先匹配的结果不是我需要的结果。 它会有,如果zX98320987是AB98320987 现在,我刚开始学习,我不能监督附加代码的作用。 但是你用外行人的话来解释一下? – Giancarlo 2014-09-13 08:19:19