2017-09-01 151 views
1

我想了解如何分析C#语句的语法。 在我的情况下,我有一个句子,每个句子必须遵循。 的语法如下:检查字符串的语法 - C#

A 'B' 是 'C'。

每个句子必须包含5个单词。我的第一句话必须是'A',第三个'是'和第四个'a'。

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

测试一句话:

狗是没有猫。

在这个例子中,测试句话是错误的,因为第四个词是“不”,而不是“一”是什么,应该对语法basend。

我读了关于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#语句的语法?

+1

“相交”不会说任何有关单词在列表中的位置,所以不会做这项工作。你想要做的是分割输入字符串并编写一个匹配模式的方法 - 或者通过硬编码if(words [0]!=“A”)return false;'等等,或者通过给它一个规则集 - 可能是一个对象列表,例如'{int Index; string RequiredWord; }'。你的第一句话令人震惊,但你的实际要求是相当温和和合理的。更新如果我有更多的理解,我会直接去德米特里的正则表达式的想法。你的代码也可以构建正则表达式字符串(然后你有3个问题) –

+1

“Dog42是Cat17”是一个有效的语法吗? –

+0

@AleksAndreev在这种情况下是的。我没有试图检查这句话是否有意义。试图找出句子是否包含我指定的语法 –

回答

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) 

可以稍微修改代码,并获得实际的第一和第二串的价值观:

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

如何:'A 7是一个数字'? – sTrenat

+1

@sTrenat:在我当前的代码中,输入'“A 7是一个数字。”'*无效*:它以*空格*(不是'A')开始,而'7'不是一个字。如果这样的字符串应该是有效的,模式应该是'@'^ \ s * A \ s + [A-Za-z0-9] + \ s +是\ s + a \ s + [A-Za-z0-9] + \。$“' –

+0

我知道它不会,只是想用数字得到一些例子:)谢谢 – sTrenat

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; 
} 
1

只是想抛出想法。我会写三类此:

  1. SentenceManager:它得到的字符串作为一个句子,有一个公共的方法public string GetWord(word_index)。例如GetWord(3)会返回已经提供给类构造函数的句子中的第3个单词。

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

  3. SyntaxChecker:该类获取一个SentenceSyntax对象和SentenceManager对象,有一个名为Check功能如果语法句子匹配返回true。

请记住,可以有成千上万的方法来使某些工作。但有几种方法可以做到这一点。

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; 

使用这个代码,我会怎么做,你也可以得到这样的情况下灵活大小写的比较,并围绕这个词修剪空间,等等 - 当然,你将不得不代码对于