我正在使用C#
在AIML files
中构建一个聊天机器人,此时此代码需要处理:
<aiml>
<category>
<pattern>a * is a *</pattern>
<template>when a <star index="1"/> is not a <star index="2"/>?</template>
</category>
</aiml>
我想做点什么:
if (user_string == pattern_string) return template_string;
但我不知道如何告诉计算机star
字符可以是任何字符,特别是可以是多个单词!
我正在考虑使用正则表达式,但我没有足够的经验。有人能帮助我吗? :)
答案 0 :(得分:2)
使用Regex
static bool TryParse(string pattern, string text, out string[] wildcardValues)
{
// ^ and $ means that whole string must be matched
// Regex.Escape (http://msdn.microsoft.com/en-us/library/system.text.regularexpressions.regex.escape(v=vs.110).aspx)
// (.+) means capture at least one character and place it in match.Groups
var regexPattern = string.Format("^{0}$", Regex.Escape(pattern).Replace(@"\*", "(.+)"));
var match = Regex.Match(text, regexPattern, RegexOptions.Singleline);
if (!match.Success)
{
wildcardValues = null;
return false;
}
//skip the first one since it is the whole text
wildcardValues = match.Groups.Cast<Group>().Skip(1).Select(i => i.Value).ToArray();
return true;
}
样本用法
string[] wildcardValues;
if(TryParse("Hello *. * * to *", "Hello World. Happy holidays to all", out wildcardValues))
{
//it's a match
//wildcardValues contains the values of the wildcard which is
//['World','Happy','holidays','all'] in this sample
}
顺便说一下,你真的不需要正则表达式,这太过分了。只需使用string.Split将模式拆分为标记,然后使用string.IndexOf查找每个标记,即可实现自己的算法。虽然使用Regex会导致更短的代码
答案 1 :(得分:0)
你觉得这对你有用吗?
Match match = Regex.Match(pattern_string, @"<pattern>a [^<]+ is a [^<]+</pattern>");
if (match.Success)
{
// do something...
}
此处 [^&lt;] + 表示一个或多个字符&lt;
如果你认为你可能有&lt;您的*中的字符,然后您只需使用。+ 而不是 [^&lt;] +
但这会有风险,因为。+ 表示任何一次或多次的角色。