正则表达式 - 获取部分字符串
问题描述:
我有我需要一些配套on.The的项目列表可能看起来像这个项目的名称列表:正则表达式 - 获取部分字符串
suzu
suzu-domestic
suzu-international
suzuran
suzuran-international
scorpion
scorpion-default
yada
yada-yada
etc
如果搜索项目是suzu
,我倒要从列表中有以下结果:含suzuran
suzu
suzu-domestic
suzu-international
但不什么。我也喜欢有以下的比赛,如果项目的搜索是suzuran
suzuran
suzuran-international
但含suzu
不什么。
在C#代码,我有东西,看起来像类似于这样:
String searchForProject = "suzu";
String regStr = @"THE_REGEX_GOES_HERE"; // The regStr will be in a config file
List<Project> projects = DataWrapper.GetAllProjects();
Regex regEx = new Regex(String.Format(regStr, searchForProject));
result = new List<Project>();
foreach (Project proj in projects)
{
if (regEx.IsMatch(proj.ProjectName))
{
result.Add(proj);
}
}
的问题是,我可以有一个正则表达式,使我得到的所有确切的项目名称匹配,而不是那些那会被startWith等价物返回? (今天我有一个regStr = @"^({0})#"
,但因为它提供了更多的点击率比它应该,这并不符合上述情形)
我会很感激,如果有人可以给我一个提示在正确的方向。谢谢 ! 马格努斯
答
所有你需要的其实
var regStr = @"^{0}\b";
是该^
锚断言在字符串的开始位置。 \b
模式匹配单词和非单词字符之间的位置,即字符串的开始或结尾。由于您使用的是Regex.IsMatch
,因此您不需要将其余字符串与.*
相匹配,这是一种冗余开销。
C#测试代码:
var projects = new List<string>() { "suzu", "suzu-domestic", "suzu-international", "suzuran", "suzuran-international", "scorpion", "scorpion-default", "yada", "yada-yada" };
var searchForProject = "suzu";
var regStr = @"^{0}\b"; // The regStr will be in a config file
var regEx = new Regex(String.Format(regStr, searchForProject));
var result = new List<string>();
foreach (var proj in projects)
{
if (regEx.IsMatch(proj))
{
result.Add(proj);
}
}
的foreach
可以用更短的LINQ代替:
var result = projects.Where(s => regEx.IsMatch(s)).ToList();
答
如果你想在一个符合LINQ和没有一个完美的解决方案正则表达式,你可以检查这个工作解决方案(演示.NETFiddle):
using System;
using System.Linq;
using System.Collections.Generic;
public class Program
{
public void Main()
{
string input = "suzu";
string s = @"suzu
suzu-domestic
suzu-international
suzuran
suzuran-international
scorpion
scorpion-default
yada
yada-yada";
foreach (var line in ExtractLines(s, input))
Console.WriteLine(line);
}
// works if "-" is your delimiter.
IEnumerable<string> ExtractLines(string lines, string input)
{
return from line in lines.Split(new char[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries) // use to split your string by line
let cleanLine = line.Contains("-") ? line.Split('-')[0] : line // use only the needed part
where cleanLine.Equals(input) // check if the output match with the input
select line; // return the valid line
}
}
答
随着负前瞻:
suzu(?!.*ran).*\b
这也将\ b。对于一个字打破
这是一个指向regular-expressions.info的[** word边界'\ b' **](http://www.regular-expressions.info/wordboundaries.html)参考的链接,以防万一您感兴趣。如果有'_'而不是'-',那么你将不得不使用类似'(?![[p]}}的东西来代替它,因为'_'是一个单词字符。 –
优秀stribizhev!我很欣赏关于LINQ的额外的_tutorial_以及对**字边界的引用**! – Metscore
至于正则表达式与纯LINQ方法:如果你使用'RegexOptions.Compiled'将静态类中的正则表达式声明为'public static readonly'字段,速度将是可比的,正则表达式将为你提供更好的灵活性和控制通过您的文本输入和输出。 –