大家好,我想请教大家一个正则表达式应该怎么写。下面是一种OQL(object query language), 我现在想验证它是否包含那个id。在括号中的是子语句,他们也有可能包含“id”, 正则表达式需要能区分主语句中的id和子语句中的id,只验证主语句是是否有id。谢谢大家!select name, id, country, city, (select id, firstname, lastname from contacts), (select id, name, amount from opportunities) from account where name like '%a%'

解决方案 »

  1.   

    本来想把id变成红色,没有到把HTML显示出来了。原来OQL应该是:
    select name, id, country, city, (select id, firstname, lastname from contacts), (select id, name, amount from opportunities) from account where name like '%a%'
      

  2.   

    还有,主语句中的id也有可能在子语句的后面或两/多个子语句中间. 例如:select name, country, city, (select id, firstname, lastname from contacts), (select id, name, amount from opportunities), id from account where name   like '%a%'select name, country, city, (select id, firstname, lastname from contacts), id, (select id, name, amount from opportunities) from account where name   like '%a%'
      

  3.   

     列名 like '^id$' 这样就行拉!
      

  4.   

    你的目标:匹配在select之后from之前,且不在()中的id。
    考虑到select的多重嵌套。彻底解决这个问题需要用到递归匹配。虽然不算很难,但是写起来就够让人头大了。可考虑的建议:1、用C#写一个解析程序,返回结果。
       个人想法:写这个解析程序都比写正则要简单!对俺们来说,正则的可读性不是很好。(大牛是例外)。
       
    2、要彻底解决多重嵌套,自己去研究一下递归匹配的语法。一下,看看有没有牛人解决这个问题。(这个匹配够难度了)
      

  5.   

    如果没有子语句的嵌套,那直接写匹配正则还是很好写的,但是既然有可能有嵌套,那就不如换种思路,先把子语句给Replace掉,然后再验证string strOQL = "select   name,   country,   city,   (select   id,   firstname,   lastname   from   contacts),   id,   (select   id,   name,   amount   from   opportunities)   from   account   where   name       like   '%a%'";
    string result = Regex.Replace(strOQL, @"\(((\((?<o>)|\)(?<-o>)|[^()])*(?(o)(?!)))\)", "");
    if (Regex.IsMatch(result, @"\bid\b"))
        MessageBox.Show("包含");
    else
        MessageBox.Show("不包含");
      

  6.   

    - -正则不难写 不过我不熟悉sql~~~楼上那个一看就知道不合格~~
    要进行sql断句~~比如:select top 10 name,id,city...
    以空格和逗号断句,遇到括号则排除,比如那个10可能经过函数计算的..那么就有可能出现任何字符,得看(号~~
    其实这已经涉及到编译原理的知识了。。并不是想象中那么简单~~
      

  7.   

    不会,我都是搜索出来,然后replace的,关注
      

  8.   

    一定要用正则表达式吗?
    换个思路 先把字符串的的'('和')'还有其中间的内容去掉
    这样就剩下主语句了 再看其中是否有"id"
    我的代码        bool IsExistID(string str)
            {
                string s=str;
                int start, end;
                while(true)                               //循环找"(.....)"
                {
                    start = s.IndexOf('(');
                    if (start == -1)
                        break;
                    end = s.IndexOf(')', start);
                    s=s.Remove(start, end - start + 1);  //将"(.....)"删掉
                }
                if (s.IndexOf("id")>=0)                  //查看剩下的主语句中是否有"id"
                    return true;
                else
                    return false;
            }
      

  9.   

    一定要用正则表达式吗?
    换个思路 先把字符串的的'('和')'还有其中间的内容去掉
    这样就剩下主语句了 再看其中是否有"id"
    我的代码        bool IsExistID(string str)
            {
                string s=str;
                int start, end;
                while(true)                               //循环找"(.....)"
                {
                    start = s.IndexOf('(');
                    if (start == -1)
                        break;
                    end = s.IndexOf(')', start);
                    s=s.Remove(start, end - start + 1);  //将"(.....)"删掉
                }
                if (s.IndexOf("id")>=0)                  //查看剩下的主语句中是否有"id"
                    return true;
                else
                    return false;
            }
      

  10.   

    hi Root_你的方法很好,就是有两个问题,希望能帮我解决一下。 当OQL是下面这个语句的时候,虽然没有id, 但是验证却能通过,也许我们需要把from以后的都replace掉,然后那个owner.id的情况也要处理一下。谢谢,select name, owner.id from account where id = '1234567890'
      

  11.   

    按楼主的要求,又加了一条过滤语句和一个条件,楼主看下是否还有不符合条件的string strOQL = "select   name,   owner.id   from   account   where   id   =   '1234567890'";
    string result = Regex.Replace(strOQL, @"\(((\((?<o>)|\)(?<-o>)|[^()])*(?(o)(?!)))\)", "");
    result = Regex.Replace(result, @"where[\s\S]*$", "", RegexOptions.IgnoreCase);
    if (Regex.IsMatch(result, @"\b(?<!\.)id\b"))
        MessageBox.Show("包含");
    else
        MessageBox.Show("不包含");
      

  12.   

    哦,新增过滤语句中where改为from,两侧再加上\b更严谨一些string strOQL = "select   name,   owner.id   from   account   where   id   =   '1234567890'";
    string result = Regex.Replace(strOQL, @"\(((\((?<o>)|\)(?<-o>)|[^()])*(?(o)(?!)))\)", "");
    result = Regex.Replace(result, @"\bfrom\b[\s\S]*$", "", RegexOptions.IgnoreCase);
    if (Regex.IsMatch(result, @"\b(?<!\.)id\b"))
        MessageBox.Show("包含");
    else
        MessageBox.Show("不包含");
      

  13.   

    呵呵,其实按这种思路,可以简化成一条过滤语句,用现有例子测试通过,楼主再测下吧,如果有不符合要求的,给出例子,我再看下string strOQL = "select   name,   owner.id   from   account   where   id   =   '1234567890'";
    string result = Regex.Replace(yourStr, @"\(((\((?<o>)|\)(?<-o>)|[^()])*(?(o)(?!)))\)|\bfrom\b[\s\S]*$", "", RegexOptions.IgnoreCase);
    if (Regex.IsMatch(result, @"\b(?<!\.)id\b"))
        MessageBox.Show("包含");
    else
        MessageBox.Show("不包含");