我有一个令牌器,其中令牌具有给定的接口:
interface IToken
{
string Str { get; } //used after the token is built to get its content
bool Success { get; } //has the informaition if the last 'TryAdd' was a success
bool Valid { get; } //has the information if the current 'Str' is complete and Valid
void TryAdd(char c); //Is called to add the next character to the token
}
一般的想法是,并行处理给定输入的每个字符的已实现令牌列表。
'NumberToken'太慢了,我试着加快速度。我想试用正则表达式,我想知道以下是否可行。
给定像String patternINTFRACEXP = @"(\A)[0-9]+?\.[0-9]+?[eE]{1}[+-]{0,1}[0-9]+?(\Z)";
这样的模式,我可以通过一次添加一个字符来逐步检查表达式是否仍然有效。我写了一些Pseudocode来说明我希望那个构建器做什么。
class PseudoCode : IToken
{
String patternINTFRACEXP = @"(\A)[0-9]+?\.[0-9]+?[eE]{1}[+-]{0,1}[0-9]+?(\Z)";
RegexBuilder builder;
public PseudoCode()
{
builder = new RegexBuilder(patternINTFRACEXP);
Success = true;
}
public string Str{ get { return builder.ToString(); } }
public bool Success { get; private set; }
public bool Valid { get { return builder.IsMatch(); } }
public void TryAdd(char c) { Success &= builder.TryAdd(c); }
}
StringBuilder和Regex的组合是否已存在?
实施(builder as RegexBuilder).TryAdd(c as Char);
的方法是什么?
答案 0 :(得分:1)
我的方法是从模式的不同步骤开始,从最长的
开始([0-9]+\.[0-9]+[eE]{1}[+-]{0,1}[0-9]+|[0-9]+?\.[0-9]+[eE]{1}[+-]{0,1}[0-9]+|[0-9]+\.[0-9]+[eE]{1}[+-]{0,1}|[0-9]+\.[0-9]+[eE]{1}|[0-9]+\.[0-9]+|[0-9]+\.|[0-9]+)
我不熟悉c#,jsut在正则表达式部分回答,不需要ungreedy运算符,因为你有'分隔符'(。,+, - ,e)已经分割了字符串。
我会用这样的不同部分做一个数组:
pattern = ["[0-9]+","\.","[0-9]+","[eE]{1}","[+-]{0,1}","[0-9]+"]
testpattern = ""
pattern.each do |p|
testpattern += "#{testpatern}#{p}|#{testpattern}"
end
testpattern.rstrip("|")
使用testpatern进行测试。 (剥离领先|最后)
它的ruby代码并没有经过测试,所以我可能在某个地方有一个bug,但想法是在每次迭代时构建模式添加新部分,最后用完整的ORed正则表达式进行测试。
希望这会有所帮助
替代解决方案:
^([0-9]+)[.]?([0-9]+|)(?:[eE]{1}([+-]{0,1}[0-9]+|)|)$
它完全匹配(如果在格式中没有预期的东西它将不匹配)并捕获整数部分,小数部分和带有符号的指数(如果有的话)。
它将匹配以e或E结尾的字符串,因此可能是您的验证部分。
详细说明:
^
< =行首(而不是字符串)
([0-9]+)
< =任意数字至少一次(第一次捕获)
[.]?
< =一个小点0或1次(我更喜欢使用转义语法的[。]语法进行阅读
([0-9]+|)
< =小数部分或没有(第二次捕获)
(?:[eE]{1}([+-]{0,1}[0-9]+|)|)
< =很多部分,详情:
(?:
< =非捕获组的开始
[eE]{1}
< = 1 e其余的大写或小写
([+-]{0,1}[0-9]+|)
< =第三个捕获组,指数是否签名或没有指定(匹配将E添加到您的字符串中)
)
< =未捕获组的结束
$
行尾