C# 使用C从驻留在DB中的字符串集自动生成正则表达式#
我在数据库中有大约100000个字符串,我想知道是否有办法从这些字符串自动生成正则表达式模式。它们都是字母字符串,使用一组英文字母。例如,不使用(X,W,V)。是否有任何函数或库可以帮助我在C#中实现这一目标?示例字符串是 KHTKC# 使用C从驻留在DB中的字符串集自动生成正则表达式#,c#,regex,C#,Regex,我在数据库中有大约100000个字符串,我想知道是否有办法从这些字符串自动生成正则表达式模式。它们都是字母字符串,使用一组英文字母。例如,不使用(X,W,V)。是否有任何函数或库可以帮助我在C#中实现这一目标?示例字符串是 KHTK 拉兹 给定这两个字符串,我的目标是生成一个正则表达式,它允许像(k,kh,kht,khtk,r,ra,raz)这样的模式不区分大小写。我已经下载并使用了一些有助于生成正则表达式的C#应用程序,但这在我的场景中并不有用,因为我需要一个过程,在这个过程中,我从db中顺序
拉兹 给定这两个字符串,我的目标是生成一个正则表达式,它允许像(k,kh,kht,khtk,r,ra,raz)这样的模式不区分大小写。我已经下载并使用了一些有助于生成正则表达式的C#应用程序,但这在我的场景中并不有用,因为我需要一个过程,在这个过程中,我从db中顺序读取字符串,并向正则表达式添加规则,以便以后可以在应用程序中重用该正则表达式或将其保存在磁盘上 我不熟悉正则表达式模式,不知道我所问的事情是否可能。如果不可能,请向我推荐一些替代方法。一种简单(有些人可能会说幼稚)的方法是创建一个正则表达式模式,将所有搜索字符串连接在一起,由替代运算符
|
分隔:
KHTK | RAZ
K | KH | KHT | KHTK | R | RA | RAZ
^K$^KH$^KHT$^KHTK$^R$^RA$^RAZ$
using System;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;
namespace ConsoleApplication
{
class Program
{
private static Random r = new Random();
// Create a string with randomly chosen letters, of a randomly chosen
// length between the given min and max.
private static string RandomString(int minLength, int maxLength)
{
StringBuilder b = new StringBuilder();
int length = r.Next(minLength, maxLength);
for (int i = 0; i < length; ++i)
{
b.Append(Convert.ToChar(65 + r.Next(26)));
}
return b.ToString();
}
static void Main(string[] args)
{
int stringCount = 10000; // number of random strings to generate
StringBuilder pattern = new StringBuilder(); // our regular expression under construction
HashSet<String> strings = new HashSet<string>(); // a set of the random strings (and their
// prefixes) we created, for verifying the
// regex correctness
// generate random strings, track their prefixes in the set,
// and add their prefixes to our regular expression
for (int i = 0; i < stringCount; ++i)
{
// make a random string, 2-5 chars long
string nextString = RandomString(2, 5);
// for each prefix of the random string...
for (int prefixLength = 1; prefixLength <= nextString.Length; ++prefixLength)
{
string prefix = nextString.Substring(0, prefixLength);
// ...add it to both the set and our regular expression pattern
if (!strings.Contains(prefix))
{
strings.Add(prefix);
pattern.Append(((pattern.Length > 0) ? "|" : "") + "^" + prefix + "$");
}
}
}
// create a regex from the pattern (and time how long that takes)
DateTime regexCreationStartTime = DateTime.Now;
Regex r = new Regex(pattern.ToString());
DateTime regexCreationEndTime = DateTime.Now;
// make sure our regex correcly matches all the strings, and their
// prefixes (and time how long that takes as well)
DateTime matchStartTime = DateTime.Now;
foreach (string s in strings)
{
if (!r.IsMatch(s))
{
Console.WriteLine("uh oh!");
}
}
DateTime matchEndTime = DateTime.Now;
// generate some new random strings, and verify that the regex
// indeed does not match the ones it's not supposed to.
for (int i = 0; i < 1000; ++i)
{
string s = RandomString(2, 5);
if (!strings.Contains(s) && r.IsMatch(s))
{
Console.WriteLine("uh oh!");
}
}
Console.WriteLine("Regex create time: {0} millisec", (regexCreationEndTime - regexCreationStartTime).TotalMilliseconds);
Console.WriteLine("Average match time: {0} millisec", (matchEndTime - matchStartTime).TotalMilliseconds / stringCount);
Console.ReadLine();
}
}
}
当将字符串数量增加10倍(至100000)时,我得到:
Regex create time: 288 millisec
Average match time: 1.25577 millisec
这是较高的,但增长不是线性的
该应用程序的内存消耗(10000个字符串)从~9MB开始,峰值为~23MB,其中必须包含正则表达式和字符串集,最后降至~16MB(垃圾收集开始了?)从中得出您自己的结论--该程序没有优化以从其他数据结构中挑出正则表达式内存消耗。这不是您问题的答案,但既然你提到你是RegEx的新手,我想指出我最近遇到了一个很棒的资源来学习和测试RegEx的感谢Oren,这是一个很大的帮助。我机器上的结果证实了你的。令人惊讶的是,对于长度从1到20个字符不等的140000个字符串,平均匹配时间为.421221毫秒。现在,我将从db中读取字符串,并创建一个类似urs的模式字符串,我将保存在db中,并在每次运行应用程序时重用它。当新字符串添加到数据库中时,模式字符串当然会被更新,这种情况并不常见。请让我知道我是否在正确的轨道上。不幸的是,我没有足够的分数来投票支持你的答案,但我还是很感激这一巨大的帮助。当在数据库中存储模式时,请记住它的大小——它的长度将是已经存在的所有字符串的倍数。如果这是一个问题,您可以使用的选项包括每次重新创建模式,并压缩它。模式应该压缩得很好,因为它几乎由前缀组成;如果需要,请查看System.IO.Compression。谢谢Oren。我过几天再谈
Regex create time: 288 millisec
Average match time: 1.25577 millisec