在 C# 中读取 Word
Read Word in C#
我有输入作为
string afterIN = "Text Field= Assignee AND Ticket Status != Deleted";
然后我用下面的代码尝试处理它:
char[] delimiterChars = { ' ', ',', '.', ':', '\t' };
string text = afterIN;
string[] words = text.Split(delimiterChars);
string str = "";
foreach (var word in words)
{
if (word != "")
{
string strDelimit = "\"";
str += strDelimit + word + strDelimit + ",";
}
}
我想要输出作为
"Text Field",
"=",
"Assignee",
"AND",
"Ticket Status",
"!=",
"Deleted"
另一种类型的输入是SQL查询,例如
SELECT # Tickets WHERE Ticket Status=Open OR Ticket Status=Pending
期望的输出被分割WHERE
:
"Ticket Status",
"=",
"Open",
"OR",
"Ticket Status",
"=",
"Pending"
在一般情况下你需要一个解析器;但是,如果可以保证源字符串
没有 comments、strings 和其他复杂的语法结构,例如
// here we should split on first 2 "AND"s
Text Filed = /* And is commented*/ "A \"AND B" /* String */ AND Ticket Status != Deleted
您可以尝试借助正则表达式进行拆分:
using System.Text.RegularExpressions;
...
string source = "Text Field = Assignee AND Ticket Status != Deleted";
// split on =, !=, and, or
// Trim() each item if you want to get rid of leading / trailing spaces
string[] items = Regex.Split(
source,
@"(!=|\band\b|=|\bor\b)",
RegexOptions.IgnoreCase);
为了处理(非常)简单 SQL(没有注释、字符串等)我们可以添加一些 Linq (到 Skip
查询的初始部分和 Take
仅 where
部分:
using System.Linq;
using System.Text.RegularExpressions;
...
string source =
@"SELECT # Tickets
WHERE Ticket Status <> Open OR Ticket Status > Pending
GROUP BY x
ORDER BY y";
string[] delimiters = new string[] {
"where",
"order",
"group",
//TODO: put all delimiters here
">", "<", "<>", "=", "!=", ">=", "<=",
"and", "or", "not"
};
string pattern = string.Join("|", delimiters
.OrderByDescending(item => item.Length)
.Select(item => item.All(c => char.IsLetter(c))
? $@"\b{item}\b"
: Regex.Escape(item)));
string[] items = Regex
.Split(source, $"({pattern})", RegexOptions.IgnoreCase)
.Select(item => item.Trim())
.SkipWhile(item => !"where".Equals(item, StringComparison.OrdinalIgnoreCase))
.Skip(1)
.TakeWhile(item => !"order".Equals(item, StringComparison.OrdinalIgnoreCase) &&
!"group".Equals(item, StringComparison.OrdinalIgnoreCase))
.ToArray();
我有输入作为
string afterIN = "Text Field= Assignee AND Ticket Status != Deleted";
然后我用下面的代码尝试处理它:
char[] delimiterChars = { ' ', ',', '.', ':', '\t' };
string text = afterIN;
string[] words = text.Split(delimiterChars);
string str = "";
foreach (var word in words)
{
if (word != "")
{
string strDelimit = "\"";
str += strDelimit + word + strDelimit + ",";
}
}
我想要输出作为
"Text Field",
"=",
"Assignee",
"AND",
"Ticket Status",
"!=",
"Deleted"
另一种类型的输入是SQL查询,例如
SELECT # Tickets WHERE Ticket Status=Open OR Ticket Status=Pending
期望的输出被分割WHERE
:
"Ticket Status",
"=",
"Open",
"OR",
"Ticket Status",
"=",
"Pending"
在一般情况下你需要一个解析器;但是,如果可以保证源字符串 没有 comments、strings 和其他复杂的语法结构,例如
// here we should split on first 2 "AND"s
Text Filed = /* And is commented*/ "A \"AND B" /* String */ AND Ticket Status != Deleted
您可以尝试借助正则表达式进行拆分:
using System.Text.RegularExpressions;
...
string source = "Text Field = Assignee AND Ticket Status != Deleted";
// split on =, !=, and, or
// Trim() each item if you want to get rid of leading / trailing spaces
string[] items = Regex.Split(
source,
@"(!=|\band\b|=|\bor\b)",
RegexOptions.IgnoreCase);
为了处理(非常)简单 SQL(没有注释、字符串等)我们可以添加一些 Linq (到 Skip
查询的初始部分和 Take
仅 where
部分:
using System.Linq;
using System.Text.RegularExpressions;
...
string source =
@"SELECT # Tickets
WHERE Ticket Status <> Open OR Ticket Status > Pending
GROUP BY x
ORDER BY y";
string[] delimiters = new string[] {
"where",
"order",
"group",
//TODO: put all delimiters here
">", "<", "<>", "=", "!=", ">=", "<=",
"and", "or", "not"
};
string pattern = string.Join("|", delimiters
.OrderByDescending(item => item.Length)
.Select(item => item.All(c => char.IsLetter(c))
? $@"\b{item}\b"
: Regex.Escape(item)));
string[] items = Regex
.Split(source, $"({pattern})", RegexOptions.IgnoreCase)
.Select(item => item.Trim())
.SkipWhile(item => !"where".Equals(item, StringComparison.OrdinalIgnoreCase))
.Skip(1)
.TakeWhile(item => !"order".Equals(item, StringComparison.OrdinalIgnoreCase) &&
!"group".Equals(item, StringComparison.OrdinalIgnoreCase))
.ToArray();