如何匹配一部分字符串并拒绝整个字符串?

时间:2018-08-21 23:20:06

标签: c# regex

我有一个包含以下四个元素的数组:
[0]: //some data
[1]: /some data
[2]: for i = 1 to 10
[3]: foreach i

我要四个正则表达式来检查
1)如果字符串以/而不是//开头
2)如果字符串以//开头
3)如果字符串以for而不是foreach开头
4)字符串是否以foreach

开头

对于//,我使用了^//.*,它运行良好,但是我不知道如何匹配/并拒绝//

对于foreach,我使用了^foreach,但我不知道怎么匹配for

编辑
forforeach只是示例数据。
可能只有for,后面没有任何内容。
而且我想使用匹配长度

3 个答案:

答案 0 :(得分:3)

这样的事情应该为您做

class PatternMatch
{
  public string Prefix { get; private set; }
  public string Suffix { get; private set; }

  private static Regex rxValid = new Regex(@"
    ^                           # start of line, followed by
    (?<pfx>                     # one of...
    ( /  ( [^/] | (?= $ ) ) ) # a slash (but not slash slash!)
    | ( //                    ) # two slashes
    | ( for(?! each )         ) # for (but not foreach)
    | ( foreach               ) # foreach
    )                           # , followed by...
    (?<sfx> .* )                # zero or more extraneous characters, followed by
    $                           # end-of-line  
  ", RegexOptions.ExplicitCapture | RegexOptions.IgnorePatternWhitespace);

  public static PatternMatch TryMatch( string s)
  {
    Match m = rxValid.Match(s);
    PatternMatch instance = m.Success ? new PatternMatch(m) : null ;
    return instance;
  }
  private PatternMatch(Match m)
  {
    if (!m.Groups["pfx"].Success | !m.Groups["sfx"].Success) throw new ArgumentOutOfRangeException("m", "The match needs to be successfull");
    this.Prefix = m.Groups["pfx"].Value;
    this.Suffix = m.Groups["sfx"].Value;
  }
}

这是一个测试用例:

static void Test()
{
  string[] text =
  {
    "//some data",
    "/some data",
    "for i = 1 to 10",
    "foreach i",
  };

  foreach (string s in text)
  {
    PatternMatch pm = PatternMatch.TryMatch(s);
    if (pm == null)
    {
      Console.WriteLine("NO MATCH: {0}", s);
    }
    else
    {
      Console.WriteLine("MATCHED:  {0}", s);
      Console.WriteLine("  Prefix: len={0}, value={1}", pm.Prefix.Length, pm.Prefix );
      Console.WriteLine("  Suffix: len={0}, value={1}", pm.Suffix.Length, pm.Suffix ); 
    }

  }
}

答案 1 :(得分:0)

字符串以/而不是//开头:^/[^/].*

字符串以//开头:^//.*

字符串以for而不是foreach开头:^for\s.*

字符串以foreach开头:^foreach\s.*

答案 2 :(得分:0)

我不确定string类已经具有StartsWith方法时为什么需要正则表达式,您可以按原样使用#2和#4要求。对于#1和#3,您可以将其与!input.StartsWith结合使用以获得结果。

这是您可以使用的扩展方法:

public static class Extensions
{
    public static bool StartsWithThisButNotThat(this string input, string startsWith, 
        string notStartsWith = null)
    {
        if (input == null) return startsWith == null;
        if (startsWith == null) return false;
        if (notStartsWith == null) return input.StartsWith(startsWith);
        return input.StartsWith(startsWith) && !input.StartsWith(notStartsWith);
    }
}

然后在您的主代码中,您可以像这样测试它:

private static void Main()
{
    var codeLines = new List<string>
    {
        "//some data",
        "/some data",
        "for i = 1 to 10",
        "foreach i",
    };

    foreach (var codeLine in codeLines)
    {
        Console.WriteLine(codeLine);

        Console.Write(" - starts with / and not //".PadRight(40, '.'));
        Console.WriteLine(codeLine.StartsWithThisButNotThat("/", "//"));

        Console.Write(" - starts with //".PadRight(40, '.'));
        Console.WriteLine(codeLine.StartsWithThisButNotThat("//"));

        Console.Write(" - starts with for and not foreach ".PadRight(40, '.'));
        Console.WriteLine(codeLine.StartsWithThisButNotThat("for", "foreach"));

        Console.Write(" - starts with foreach".PadRight(40, '.'));
        Console.WriteLine(codeLine.StartsWithThisButNotThat("foreach"));

        Console.WriteLine("\n" + new string('-', Console.WindowWidth));
    }

    GetKeyFromUser("\nDone! Press any key to exit...");
}

输出

enter image description here