![](/img/trans.png)
[英]Regex - Match a string only when it contains any alphabetic characters
[英]Regex A string only contains allowed characters and limit the occurances of characters
这是我的角色出现限制。
Dictionary<string,int> chracterLimit=new Dictionary<string,int>{{"c",1,"a",2}};
这是我的输入字符串...
var mystring="caac";
在这里,我检查LINQ是否对该字符有效,并且使用的字符数超过允许的限制。
bool checkstringvalid=!mystring
.ToCharArray()
.Select(c => c.ToString())
.GroupBy(g => g)
.ToList()
.ToDictionary(
d => d.FirstOrDefault(),
d => d.Count())
.Any(z => z.Value > chracterGroup[z.Key]);
以上条件的输出为>这是无效的字符串。 因为c的出现为2,但允许的限制仅为1。
当我使用此功能时,要花费大量时间处理批量数据...而我的问题是,如何才能更轻松地检查此数据?
您能给我一个解决方案,以通过正则表达式对其进行检查吗? 我的想象像/ a {0,2} / / c {0,1} /
提前致谢!:)
LINQ引擎非常智能,因此您不太可能从当前的性能中获得很大的性能提升。 您可以做的一件事就是减少不必要的操作。 您所拥有的东西的更干净的版本是:
int s;
bool violation = myString.GroupBy(c => c.ToString())
.Any(g => characterLimit.TryGetValue(g.Key, out s) && s < g.Count());
这消除了从字符串到字符数组,列表到字典的转换。
对于比这更快的任何事情,您都需要放弃LINQ并采用迭代方法。
当使用符号工作时,让我们使用字符而不是字符串 (我们不希望使用过多的ToString()
,不是吗?):
Dictionary<char, int> chracterLimit = new Dictionary<char,int>{
{'c', 1},
{'a', 2}
};
然后让我们尽早发现计数器示例,即,如果我们有"aaaaaaaaa....aaa"
我们只需要读取前 3
a
,而不是整个字符串:
Dictionary<char, int> actual = new Dictionary<char, int>();
bool checkStringValid = true;
foreach (char c in mystring) {
int count = 0;
if (actual.TryGetValue(c, out count))
actual[c] = ++count;
else
actual.Add(c, ++count);
if (chracterLimit.TryGetValue(c, out var limit)) {
if (count > limit) {
checkStringValid = false; // limit exceeded
break;
}
}
else {
checkStringValid = false; // invalid charcater detected
break;
}
}
上面的代码是对速度的优化; 如果您仅在寻找更具可读性的解决方案:
bool checkstringvalid = !mystring
.GroupBy(c => c)
.Any(chunk => chracterLimit.TryGetValue(chunk.Key, out var limit)
? chunk.Skip(limit).Any()
: true);
您的LINQ表达式具有很多转换。
怎么样呢?
bool IsStringCompliant (string str, Dictionary<char><int> limits)
{
var lim = new Dictionary<char><int>(limits); // copy dict, allows re-use
foreach (var c in str) {
if (lim.ContainsKey(c)) {
lim[c] -= 1;
if (lim[c] <= 0) return false;
}
else return <<whatever result you want when a char is not in dict>>
}
return true;
}
然后执行此操作以使用该功能。
var characterLimit = new Dictionary<string,int>{{'c',1,'a',2}};
var mystring="caac";
bool checkstringvalid = IsStringCompliant(mystring, characterLimit);
由于某些原因,这将很快。
char
而不是长度为1的string
变量。 另外,对于下一个程序员而言,它更容易理解。
我不知道您为什么要在这里使用正则表达式解决方案。 绝对,我不会更快。 可以说,如果超出简单示例的范围,它甚至会变得更加复杂和复杂。
仅出于演示目的,这是将您的原始条件转换为正则表达式:
c
a
^(?![^c\n]*c[^c\n]*c)(?![^a\n]*a[^a\n]*a[^a\n]*a).*$
这里的想法是断言一个紫罗兰的规则,上面的规则:两个c
或三个a
使用否定的前瞻性以及修改后的否定字符类.
。 还有其他方法可以做到这一点。 您应该已经确信不要将正则表达式用于此任务。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.