简体   繁体   English

RegEx-请协助建立此RegEx

[英]RegEx - Please help in forming this RegEx

Can you please help me to write regular expression for this. 您能帮我为此写正则表达式吗?

Name = "Windows Product for .Net" 名称=“ Windows产品.Net”
Type = "Software Programming" 类型=“软件编程”
Quantity = "Pack of 3" 数量=“ 3包”

I want to do a match like this in c# for which I need RegEx. 我想在C#中进行这样的匹配,为此我需要RegEx。

If Name.contains(".Net") && (Type.Contains("Programming") || Type.Contains("Hardware")
{
// output will be a Match.
}
else 
{
// no match.
}

The approach I want to take here is , specify regular expression for each condition and then apply logical operand && , logical grouping paranthesis and then logical operand ||. 我在这里要采用的方法是,为每个条件指定正则表达式,然后应用逻辑操作数&&,逻辑分组括号和逻辑操作数||。 I have come up with all regular expressions for these. 我为这些想出了所有正则表达式。 How can I provide logical operands for each of them to execute in appropriate order? 如何为每个逻辑操作数提供以适当顺序执行的逻辑操作数?

   string Name = "Windows Product for .Net";
   string Type = "Software Programming";

   string patternForName = ".*Net";
   Regex rgxName = new Regex(patternForName);
   Match matchName = rgx.Match(Name);
   string patternForType = ".*Programming";
   Regex rgxType = new Regex(patternForType);
   Match matchType = rgx.Match(Type);

   string patternForType1 = ".*Hardware";
   Regex rgxType1 = new Regex(patternForType1);
   Match matchType1 = rgx.Match(Type);

Please note - We are making it dynamic, in the sense the patterns , operands and regEx are coming from xml file. 请注意-从某种意义上来说,patterns,操作数和regEx来自xml文件,我们正在使其变得动态。 So that's why I do not want to write one big regEx for above. 所以这就是为什么我不想为上面写一个大的regEx。

First of all you don't need a leading .* in your expression unless you want the whole match (ie when working with matches). 首先,除非您需要整个匹配项(即在使用匹配项时),否则表达式中不需要前导.* Just for a simple "is it there" you won't need it as the pattern might match any position. 只需简单的“是否在那儿”,您就不需要它了,因为该模式可以匹配任何位置。

Just use one regular expression for each field (ie one for Name , one for Type , one for Quantity : 只需对每个字段使用一个正则表达式(即,一个用于Name ,一个用于Type ,一个用于Quantity

string patternForName = "\\.Net"; // escaping the dot so it will match real dots only
string patternForType = "Programming|Hardware"; // | will result in "left side or right side"
string patternForQuantity = ".?"; // will match any string, even empty ones

To check everything: 要检查所有内容:

bool match = rgxName.IsMatch(Name) && rgxType.IsMatch(Type) && rgx.IsMatch(Quantity);

You can make them dynamic without using regex. 您可以使它们动态,而无需使用正则表达式。 Using regex won't really save you any time or effort, since the code's going to be about the same size either way. 使用正则表达式并不能真正节省您的时间或精力,因为两种方式的代码大小都差不多。 Following your pattern above, you can do something like this: 按照上面的模式,您可以执行以下操作:

var names = new[] { "Net", "Programming" };
var types = new[] { "Hardware" };

bool matchFound = true;

foreach (string n in names)
    matchFound &= Name.Contains(n);

foreach (string t in types)
    matchFound |= Type.Contains(t);

The above code assumes you want to match all of "names" and any of "types", but you can substitute any logic you want. 上面的代码假定您要匹配所有“名称”和任何“类型”,但是您可以替换所需的任何逻辑。

The real crux of your problem is these boolean combinations; 这些问题的真正症结在于这些布尔组合。 regex won't help you with the logic for those, so you're better off using string.Contains unless the patterns you're looking for become much more variable. regex不会帮助您解决这些问题,因此最好使用string.Contains除非您要寻找的模式变得更加可变。 Regex is distracting you from your real goal here, in my opinion. 我认为正则表达式会分散您的注意力,使您无法真正实现目标。

if (rgxName.IsMatch(Name) && (rgxType.IsMatch(Type) || rgxType1.IsMatch(Type))
{
...
}

In .NET, Regex.Match matches anywhere in the string, so you don't need the any-characters (.*) prefix on your pattern. 在.NET中,Regex.Match匹配字符串中的任何位置,因此您不需要在模式上使用任何字符(。*)前缀。 So, to check for ".NET", it would simply be: 因此,要检查“ .NET”,只需:

Regex regexName = new Regex(@"\.NET", RegexOptions.IgnoreCase);
// IsMatch returns true/false, Match returns a Match object
bool nameMatches = regexName.IsMatch(name);

Your patterns for Programming and Hardware would just be 您的编程和硬件模式将是

new Regex(@"Programming", RegexOptions.IgnoreCase) // Or leave out IgnoreCase if you're case-sensitive
new Regex(@"Hardware")

If you have a list of Name patterns and a list of type patterns, you could do something similar to this: 如果您有一个名称模式列表和一个类型模式列表,则可以执行以下操作:

bool nameIsMatch = false;
bool typeIsMatch = false;

foreach (string namePattern in namePatterns)
{
    nameIsMatch = nameIsMatch || Regex.IsMatch(nameString, namePattern);
}

foreach (string typePattern in typePatterns)
{
    typeIsMatch = typeIsMatch || Regex.IsMatch(typeString, typePattern);
}

if (nameIsMatch && typeIsMatch)
{
    // Whatever you want to do
}

patternForName = ".Net" patternForType = "Programming" patternForType1 = "Hardware" patternForName =“ .Net” patternForType =“正在编程” patternForType1 =“硬件”

You might find The Regex Coach to be useful. 您可能会发现Regex教练很有用。

It sounds like you're asking how you should handle the logical part of the problem. 听起来您好像在问应该如何处理问题的逻辑部分。 If you're pulling it from an xml file, you could structure your file in the way you want to structure your logic. 如果要从xml文件中提取文件,则可以按照想要构建逻辑的方式来构建文件。

for example, have And and Or groups: 例如,具有And和Or组:

<And>
   <Name Match=".Net"/>
   <Or>
      <Type Match="Programming"/>
      <Type Match="Hardware"/>
   </Or>
</And>

Create classes for each of these types. 为每种类型创建类。 For brevity, I didnt define the classes with properties or create constructors, but you can fill them out however you want: 为简便起见,我没有使用属性定义类或创建构造函数,但是可以根据需要填写它们:

class YourType
{
   string Name;
   string Type;
   string Quantity;
}

abstract class Test
{
   public abstract bool RunTest(YourType o);
}

class AndTest : Test
{
   public List<Test> Children;
   public bool RunTest(YourType o)
   {
      foreach (var test in Children)
      {
         if (!test.RunTest(o)) return false;
      }
      return true;
   }
}

class OrTest : Test
{
   public List<Test> Children;
   public bool RunTest(YourType o)
   {
      foreach (var test in Children)
      {
         if (test.RunTest(o)) return true;
      }
      return false;
   }
}

class NameTest : Test
{
   public string Match;

   public bool RunTest(YourType o)
   {
      return o.Name.Contains(Match);
   }
}

class TypeTest : Test
{
   public string Match;

   public bool RunTest(YourType o)
   {
      return o.Type.Contains(Match);
   }
}

Build the class structure from the xml file and just call RunTest from the top level Test. 从xml文件构建类结构,然后仅从顶级Test调用RunTest。 This way you can do any type of logic youd like. 这样,您可以执行所需的任何类型的逻辑。 I just used Contains instead of a Regex for ease of the example, but you can easily replace the string match with a regex match. 为了简化示例,我只使用了Contains而不是Regex,但是您可以轻松地将字符串匹配替换为regex匹配。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM