检查字符串的语法 - C#

时间:2017-09-01 18:27:19

标签: c# string linq string-comparison

我试图找出如何分析C#中句子的语法。 在我的情况下,我有一个句法,每个句子必须遵循。 语法如下所示:

  

A' B'是一个' C'。

每个句子必须包含五个单词。我的句子的第一个字必须是“A'”,第三个字是'第四个' a'。

现在我想检查一个符合我语法的测试句。

测试句:

  

狗不是猫。

在这个例子中,测试句子是错误的,因为第四个单词是' no'而不是' a'什么应该基于语法。

我读到LINQ,我可以查询包含一组指定单词的句子。

代码看起来像这样:

//Notice the third sentence would have the correct syntax
string text = "A Dog is no Cat. My Dog is a Cat. A Dog is a Cat.";

//Splitting text into single sentences
string[] sentences = text.Split(new char[] { '.'});

//Defining the search terms
string[] wordToMatch ={"A", "is"};

//Find sentences that contain all terms I'm looking for
var sentenceQuery = from sentence in sentences
        let w = sentence.Split(new Char[] {'.'})
        where w.Distinct().Intersect(wordsToMatch).Count == wordsToMatch.Count()
        select sentence;

使用此代码,我可以检查句子是否包含我要查找的术语,但问题是它没有检查句子中单词的位置。 有没有办法可以检查位置,或者用C#检查句子语法的更好方法?

4 个答案:

答案 0 :(得分:8)

尝试使用正则表达式,如下所示:

using System.Text.RegularExpressions;

...

string source = "A Dog is no Cat.";

bool result = Regex.IsMatch(source, @"^A\s+[A-Za-z0-9]+\s+is\s+a\s+[A-Za-z0-9]+\.$");  

模式说明:

 ^           - start of the string (anchor)
 A           - Letter A 
\s+          - one or more whitelines (spaces)
[A-Za-z0-9]+ - 1st word (can contain A..Z, a..z letters and 0..9 digits)
\s+          - one or more whitelines (spaces) 
 is          - is 
\s+          - one or more whitelines (spaces) 
 a           - a
\s+          - one or more whitelines (spaces)
[A-Za-z0-9]+ - 2nd word (can contain A..Z, a..z letters and 0..9 digits)
\.           - full stop 
 $           - end of the string (anchor)

您可以稍微修改代码并获取实际的第1和第2个字符串'值:

string source = "A Dog is a Cat."; // valid string

string pattern =
   @"^A\s+(?<First>[A-Za-z0-9]+)\s+is\s+a\s+(?<Second>[A-Za-z0-9]+)\.$";

var match = Regex.Match(source, pattern); 

if (match.Success) {
  string first = match.Groups["First"].Value;   // "Dog"
  string second = match.Groups["Second"].Value; // "Cat"

  ... 
}  

答案 1 :(得分:2)

正则表达式适用于此,并且将是最简洁的,但可能不是最易读的解决方案。这是一个简单的方法,如果句子有效,它将返回true:

private bool IsSentenceValid(string sentence)
{
    // split the sentence into an array of words
    char[] splitOn = new char[] {' '};
    string[] words = sentence.ToLower().Split(splitOn); // make all chars lowercase for easy comparison

    // check for 5 words.
    if (words.Length != 5)
        return false;

    // check for required words
    if (words[0] != "a" || words[2] != "is" || words[3] != "a")
        return false;

    // if we got here, we're fine!
    return true;
}

答案 2 :(得分:1)

只想提出想法。我会写三个类:

  1. SentenceManager:将字符串作为句子并具有公共方法public string GetWord(word_index)。例如GetWord(3)将返回已给予类构造函数的句子中的第3个单词。

  2. SentenceSyntax:在这堂课中,你可以说出你的句子必须有多少个单词。必须知道哪些单词,你也可以设置这些单词的索引。

  3. SyntaxChecker:此类获取一个SentenceSyntax对象和一个SentenceManager对象,并且有一个名为Check的函数,如果语法与句子匹配,则返回true。

  4. 记住,可以通过数千种方法让某些东西发挥作用。但是有几种方法可以做到。

答案 3 :(得分:0)

你绝对应该使用正则表达式或类似Dmitry has answered

之类的东西

只是为了踢,我想按你自己的方式去做。如果我疯了,我就该怎么做:)

//Notice the third sentence would have the correct syntax
string text = "A Dog is no Cat.My Dog is a Cat.A Dog is a Cat.";

//Splitting text into single sentences
string[] sentences = text.Split(new char[] { '.' });

string[] wordsToMatch = { "A", "*", "is", "a", "*" };

var sentenceQuery = from sentence in sentences
                    let words = sentence.Split(' ')
                    where words.Length == wordsToMatch.Length && 
                          wordsToMatch.Zip(words, (f, s) => f == "*" || f == s).All(p => p)
                    select sentence;

使用此代码,您还可以获得灵活性,例如不区分大小写的比较,修剪单词周围的空间等等 - 当然您必须为此编码