c#regex匹配排除第一个和最后一个字符

时间:2017-12-21 18:07:03

标签: c# regex

我对正则表达式一无所知,所以我要求这个伟大的社区帮助我。 在SO的帮助下,我设法编写了这个正则表达式:

    string input = "((isoCode=s)||(isoCode=a))&&(title=s)&&((ti=2)&&(t=2))||(t=2&&e>5)";
    string pattern = @"\((?>\((?<DEPTH>)|\)(?<-DEPTH>)|.?)*(?(DEPTH)(?!))\)|&&|\|\|";
    MatchCollection matches = Regex.Matches(input, pattern);
    foreach (Match match in matches)
    {
        Console.WriteLine(match.Groups[0].Value);
    }

结果是:

((isoCode=s)||(isoCode=a))
&&
(title=s)
&&
((ti=2)&&(t=2))
||
(t=2&&e>5)

但我需要这样的结果(没有第一个/最后一个“(”,“)”):

(isoCode=s)||(isoCode=a)
&&
title=s
&&
(ti=2)&&(t=2)
||
t=2&&e>5

可以吗?我知道我可以使用substring (删除第一个和最后一个字符),但我想知道它是否可以用正则表达式完成。

2 个答案:

答案 0 :(得分:4)

您可以使用

\((?<R>(?>\((?<DEPTH>)|\)(?<-DEPTH>)|[^()]+)*(?(DEPTH)(?!)))\)|(?<R>&&|\|\|)

请参阅regex demo,抓取群组“R”值。

<强>详情

  • \( - 开放(
  • (?<R> - R命名组的开头:
    • (?> - 原子组的开始:
      • \((?<DEPTH>)| - 一个开放的(和一个空字符串被推送到DEPTH组筹码或
      • \)(?<-DEPTH>)| - 结束)并从DEPTH组筹码中弹出一个空字符串或
      • [^()]+ - 除()
      • 以外的1个字符
    • )* - 零次或多次重复
    • (?(DEPTH)(?!)) - 一个条件构造,用于检查close括号和开括号的数量是否平衡
  • ) - R已命名群组
  • 的结尾
  • \) - 结束)
  • | - 或
  • (?<R>&&|\|\|) - 另一个匹配2个子模式中的任何一个的R组:
    • && - &&子字符串
    • | - 或
    • \|\| - ||子字符串。

enter image description here

C#代码:

var pattern = @"\((?<R>(?>\((?<DEPTH>)|\)(?<-DEPTH>)|[^()]+)*(?(DEPTH)(?!)))\)|(?<R>&&|\|\|)";
var results = Regex.Match(input, pattern)
    .Cast<Match>()
    .Select(m => m.Groups[1].Value)
    .ToList();

答案 1 :(得分:1)

你可以使用下面的正则表达式,但我仍然强烈建议你为此编写一个合适的解析器,而不是使用正则表达式。

代码

See regex in use here

\(((?>\((?<DEPTH>)|\)(?<-DEPTH>)|.?)*(?(DEPTH)(?!)))\)|&{2}|‌​\|{2}

用法

See regex in use here

using System;
using System.Text.RegularExpressions;

public class Test
{
    public static void Main()
    {
        string input = "((isoCode=s)||(isoCode=a))&&(title=s)&&((ti=2)&&(t=2))||(t=2&&e>5)";
        string pattern = @"\(((?>\((?<DEPTH>)|\)(?<-DEPTH>)|.?)*(?(DEPTH)(?!)))\)|&{2}|\|{2}";
        MatchCollection matches = Regex.Matches(input, pattern);
        foreach (Match match in matches)
        {
            Console.WriteLine(match.Groups[1].Success ? match.Groups[1].Value : match.Groups[0].Value);
        }
    }
}

结果

(isoCode=s)||(isoCode=a)
&&
title=s
&&
(ti=2)&&(t=2)
||
t=2&&e>5