如何匹配不包含字符串A的字符串A.

时间:2011-10-22 02:31:46

标签: c# regex

.*tan(.*tan(.*)).*开始,只有.*tan(.*tan(.*)).*,我想匹配内部tan(.*)


正则表达式

tan\([0-9a-zA-Z\.\+\-\*\/\(\)![tan]]+\)

实施例

自:

tan(80.1*tan(81.7+(80.9+81.5)))+81.9

我想提取内心:

tan(81.7+(80.9+81.5))

但不是:

tan(80.1*tan(81.7+(80.9+81.5)))

4 个答案:

答案 0 :(得分:2)

您可以使用三个正则表达式。 (我知道!疯了,不是吗?)

首先提取:

^tan\(.*?tan\(.*?\).*?\)$

然后提取:

^(?=(tan\(.*?))tan\(.*?\).*$

然后提取:

^tan\(.*?\)(?=(.*?\).*?))$

如果你正在使用Perl,那就容易多了:

$mystr =~ s\^.*?tan\(.*?(tan\(.*?\)).*?\).*$\$1\;

修改

我不知道完全你想要什么,但从你对@ Thorbear的帖子的评论判断,我不认为你应该使用正则表达式。你无法单独用[C#]正则表达式解析无上下文语法。

您需要的是表达式解析器,而不是正则表达式。

答案 1 :(得分:1)

稍微不确定您的要求......但像tan\(.*?(tan\(.*\))\)这样的内容会将内部tan()存储在$1

对于您的角色群组,您无需转义字符[0-9a-zA-Z.+*/-]即可,只需注意放置-的位置

编辑:
如果你在彼此内部有一个未知数量的tan(),你需要像tan\((.(?!tan))*?\)这样的东西来捕获最里面的一个。但是,之后您必须平衡括号,因为像tan(80.1*tan(81.7+(80.9+81.5)))这样的主题会返回匹配tan(81.7+(80.9+81.5)。此外,如果您的主题看起来像tan(80.1*tan(81.7+(80.9+81.5)+(80.9+81.5))),则该模式将无法捕获最后一个(80.9+81.5),删除最后一个?将解决此问题,但之后您将遇到tan(80.1*tan(81.7+(80.9+81.5)))+(80.9+81.5)等主题的问题因为它也会捕获最后一个表达式。

底线如上所述,这不仅仅是正则表达式的任务。

答案 2 :(得分:1)

static void Main(string[] args){
    var str = "tan(80.1*tan(81.7+(80.9+81.5)))+81.9";

    Console.WriteLine(innerTan(str));
}
static string innerTan(string str){
    const string token = "tan(";
    if(!str.Contains(token))
        return String.Empty;

    var spos = str.IndexOf(token);
    var epos = spos + token.Length;
    var balance = 1;
    for(var i = epos ;i < str.Length;++i){
        switch (str[i]){
        case '(':
            ++balance;break;
        case ')':
            --balance;break;
        }
        if(balance == 0){
            epos = i;
            break;
        }
    }
    var innerText = str.Substring(spos + token.Length, epos - spos);
    if(innerText.Contains(token))
        return innerTan(innerText);
    else
        return str.Substring(spos, epos - spos + 1);
}

答案 3 :(得分:0)

由于我无法使用运算符andnot来过滤掉最内在的tan,我终于尝试了:

public String MatchExtra(string head, string extra)
{
    string result = "";

    if (!head.Contains(extra))
        return head;

    string criteria = extra + "\\([a-zA-Z0-9\\.\\+\\-\\*\\/]+\\)";
    MatchCollection match1 = Regex.Matches(head, criteria, RegexOptions.IgnoreCase);
    foreach (Match bracket_match in match1)
    {
        if (bracket_match.Success)
        {   // not finish if bracket have bracket
            for (int y = 0; y < bracket_match.Captures.Count; y++)
            {
                string a = bracket_match.Captures[y].ToString();
                string b = bracket_match.Captures[y].ToString().Substring(extra.Length + 1, bracket_match.Captures[y].ToString().Length - extra.Length - 2);
                result = MatchExtra(bracket_match.Captures[y].ToString().Substring(extra.Length + 1, bracket_match.Captures[y].ToString().Length - extra.Length - 2), extra);
                return result;
            }
        }
    }

    string criteria2 = extra + "\\(.*\\)";
    MatchCollection match2 = Regex.Matches(head,  criteria, RegexOptions.IgnoreCase);
    foreach (Match bracket_match in match2)
    {
        if (bracket_match.Success)
        {   // not finish if bracket have bracket
            for (int y = 0; y < bracket_match.Captures.Count; y++)
            {
                string a = bracket_match.Captures[y].ToString();
                string b = bracket_match.Captures[y].ToString().Substring(extra.Length+1, bracket_match.Captures[y].ToString().Length - extra.Length -2);
                result = MatchExtra(bracket_match.Captures[y].ToString().Substring(extra.Length+1, bracket_match.Captures[y].ToString().Length - extra.Length-2), extra);
                return result;
            }
        }
    }
    return result;
}