我在我的数据库中有一个世界上每个城市的列表,并且有一个用C#编写的应用程序,需要搜索传入的字符串以确定我的任何城市是否存在于该字符串中。但是,我在制定Reg模式时遇到了问题,因为有些城市有两个词,比如“旧金山”。感谢您提前提供任何帮助。
答案 0 :(得分:1)
最简单的方法可能是在内存中创建所有城市的数组(select name from cities
),然后使用正则表达式或简单字符串方法查看文本中是否找到这些城市。
List<string> cities = GetCitiesFromDatabase(); // need to implement this yourself
string text = @"the text containign city names such as Amsterdam and San Francisco";
bool containsACity = cities.Any(city => text.Contains(city)); //To search case insensitive, add StringComparison.CurrentCultureIgnoreCase
IEnumerable<string> containedCities = cities.Where(city => text.Contains(city));
为了确保“阿姆斯特丹”在“阿姆斯特丹”上不匹配,您可以使用正则表达式而不是包含:
bool containsACity = cities.Any(city => Regex.IsMatch(text, @"\b"+Regex.Escape(city))+@"\b")
// Add RegexOptions.IgnoreCase for case insensitive matches.
IEnumerable<string> containedCities = cities.Where(city => Regex.IsMatch(text, @"\b"+Regex.Escape(city))+@"\b");
或者,您可以构建一个大的正则表达式来搜索任何城市并执行一次:
string regex = @"\b(?:" + String.Join("|", cities.Select(city => Regex.Escape(city)).ToArray()) + @")\b"
bool containsACity = Regex.IsMatch(text, regex, RegexOptions.IgnoreCase);
IEnumerable<string> containedCities = Regex.Matches(text, regex, RegexOptions.IgnoreCase).Cast<Match>().Select(m => m.Value);
您可以通过缓存城市列表或缓存正则表达式来提高这些调用的效果(并通过创建static readonly Regex object with RegexOptions.Compiled进一步改进)。
另一个解决方案是在数据库中计算,而不是在内存中存储本地城市列表,将输入发送到数据库并在数据库中使用LIKE语句或Regex来比较城市列表与文本。根据城市的数量和文本的大小,这可能是一个更快的解决方案,但这是否可行取决于所使用的数据库。