在做一个邮件程序,求一个正则表达式
字串1:=?GB2312?B?vfHEv7HqobDT0brDxvPStaGxzNi/rw==?=
上面这个字串用如下的正则可以分解出:字符集、编码方式、内容。
正则: string strRegEx=@"\=\?(?<Charset>\S+)\?(?<Encoding>\w)\?(?<Content>\S+)\?\=";
但如果有重复的字串,如下面的:
=?utf-8?Q?=E6=84=9F=E8=B0=A2=E6=82=A8=E5=9C=A8=E7=8C=AA=E5=85=AB=E6=88=92=E7=BD=91=E9=80=89=E5=AE=9A9698?==?utf-8?Q?=E5=8F=B7=E4=BB=BB=E5=8A=A1=E4=B8=AD=E6=A0=87=E4=BD=9C=E5=93=81=EF=BC=8C=E8=AF=B7=E7=A1=AE=E8=AE=A4=E4=BB=BB=E5=8A=A1=E5=AE=8C=E6=88=90=E3=80=82?=
就无法用上面的正则解析了,请问高手,如何写一个正则,能同时适用上面两种情况,且遇到第二种情况时,能把内容相加,而字符集和编码方式不加。

解决方案 »

  1.   

    不是很理解你的需求,试下下面的正则,如果不满足你的要求,给出第二种情况下你要的结果\=\?(?<Charset>[^?]*)\?(?<Encoding>\w)\?(?<Content>[^?]*)\?\=
      

  2.   

    string test = "=?utf-8?Q?=E6=84=9F=E8=B0=A2=E6=82=A8=E5=9C=A8=E7=8C=AA=E5=85=AB=E6=88=92=E7=BD=91=E9=80=89=E5=AE=9A9698?==?utf-8?Q?=E5=8F=B7=E4=BB=BB=E5=8A=A1=E4=B8=AD=E6=A0=87=E4=BD=9C=E5=93=81=EF=BC=8C=E8=AF=B7=E7=A1=AE=E8=AE=A4=E4=BB=BB=E5=8A=A1=E5=AE=8C=E6=88=90=E3=80=82?=";
    MatchCollection mc = Regex.Matches(test, @"\=\?(?<Charset>[^?]*)\?(?<Encoding>\w)\?(?<Content>[^?]*)\?\=");
    foreach (Match m in mc)
    {
        richTextBox1.Text += m.Groups["Charset"].Value + "\n";
        richTextBox1.Text += m.Groups["Encoding"].Value + "\n";
        richTextBox1.Text += m.Groups["Content"].Value + "\n";
    }
    输出:
    utf-8
    Q
    =E6=84=9F=E8=B0=A2=E6=82=A8=E5=9C=A8=E7=8C=AA=E5=85=AB=E6=88=92=E7=BD=91=E9=80=89=E5=AE=9A9698
    utf-8
    Q
    =E5=8F=B7=E4=BB=BB=E5=8A=A1=E4=B8=AD=E6=A0=87=E4=BD=9C=E5=93=81=EF=BC=8C=E8=AF=B7=E7=A1=AE=E8=AE=A4=E4=BB=BB=E5=8A=A1=E5=AE=8C=E6=88=90=E3=80=82
      

  3.   

    致 root_大侠:
    基本上就是这个意思了,但是只需要Content的值相加,Charset和Encoding不需要相加,还有,不知道你上面的正则在下面情况下也是正确的吗?
    string test="=?GB2312?B?vfHEv7HqobDT0brDxvPStaGxzNi/rw==?="
    请大侠再次赐教,非常感谢。
      

  4.   


    楼主自己试下就知道了,这种情况的结果是
    GB2312
    B
    vfHEv7HqobDT0brDxvPStaGxzNi/rw==
    我大致明白楼主Content的值相加的意思,但是不知道衔接部分的规则,所以还需要楼主把第二种情况的结果给出来我看下
    这是我猜测的结果,楼主看下对不对string test = "=?utf-8?Q?=E6=84=9F=E8=B0=A2=E6=82=A8=E5=9C=A8=E7=8C=AA=E5=85=AB=E6=88=92=E7=BD=91=E9=80=89=E5=AE=9A9698?==?utf-8?Q?=E5=8F=B7=E4=BB=BB=E5=8A=A1=E4=B8=AD=E6=A0=87=E4=BD=9C=E5=93=81=EF=BC=8C=E8=AF=B7=E7=A1=AE=E8=AE=A4=E4=BB=BB=E5=8A=A1=E5=AE=8C=E6=88=90=E3=80=82?=";
    //string test = "=?GB2312?B?vfHEv7HqobDT0brDxvPStaGxzNi/rw==?=";
    test = Regex.Replace(test, @"\?==\?[^?]*\?\w\?", "");
    MatchCollection mc = Regex.Matches(test, @"\=\?(?<Charset>[^?]*)\?(?<Encoding>\w)\?(?<Content>[^?]*)\?\=");
    foreach (Match m in mc)
    {
        richTextBox1.Text += m.Groups["Charset"].Value + "\n";
        richTextBox1.Text += m.Groups["Encoding"].Value + "\n";
        richTextBox1.Text += m.Groups["Content"].Value + "\n";
    }
    //输出
    utf-8
    Q
    =E6=84=9F=E8=B0=A2=E6=82=A8=E5=9C=A8=E7=8C=AA=E5=85=AB=E6=88=92=E7=BD=91=E9=80=89=E5=AE=9A9698=E5=8F=B7=E4=BB=BB=E5=8A=A1=E4=B8=AD=E6=A0=87=E4=BD=9C=E5=93=81=EF=BC=8C=E8=AF=B7=E7=A1=AE=E8=AE=A4=E4=BB=BB=E5=8A=A1=E5=AE=8C=E6=88=90=E3=80=82
      

  5.   


    因为楼主只要一组结果,所以可以这样写,那就把匹配不成功的情况考虑进去了string test = "=?utf-8?Q?=E6=84=9F=E8=B0=A2=E6=82=A8=E5=9C=A8=E7=8C=AA=E5=85=AB=E6=88=92=E7=BD=91=E9=80=89=E5=AE=9A9698?==?utf-8?Q?=E5=8F=B7=E4=BB=BB=E5=8A=A1=E4=B8=AD=E6=A0=87=E4=BD=9C=E5=93=81=EF=BC=8C=E8=AF=B7=E7=A1=AE=E8=AE=A4=E4=BB=BB=E5=8A=A1=E5=AE=8C=E6=88=90=E3=80=82?=";
    //string test = "=?GB2312?B?vfHEv7HqobDT0brDxvPStaGxzNi/rw==?=";
    test = Regex.Replace(test, @"\?==\?[^?]*\?\w\?", "");
    Match m = Regex.Match(test, @"\=\?(?<Charset>[^?]*)\?(?<Encoding>\w)\?(?<Content>[^?]*)\?\=");
    if (m.Success)
    {
        richTextBox1.Text += m.Groups["Charset"].Value + "\n";
        richTextBox1.Text += m.Groups["Encoding"].Value + "\n";
        richTextBox1.Text += m.Groups["Content"].Value + "\n";
    }
    else
    {
        richTextBox1.Text += "匹配不成功!";
    }
      

  6.   

    致 root_ 大侠:
    大侠真是高手啊,不用我多说,就知道小弟想要怎么样的效果。
    上面您写的正则完全符合要求,但现在有一种特殊情况,如下面:
    string test="Yahoo! =?BIG5?B?wXC3+Q==?=: =?BIG5?B?p0Gkd7NRwdy90A==?=! =?BIG5?B?pd+nWaVbpEo=?= a717fe877 .";也就是在第一个 =? 之前有一个串:Yahoo! ,在最后面一个 ?= 的后面有一个串:a717fe877 .这两个串是没有被编码的,要单独提取出来,正则要怎么写?
    也即:最后取得的Content应该等于第一个=?之前的串 + 您上面的正则取的串 + 最后一个?=之后的串
    当然,这是特殊情况,大部分情况下用您上面的正则就可以了。
    请大侠再次赐教,不胜感激。
      

  7.   

    在ROOT_上加个(?<Head>[^=]*)?\=\?(?<Charset>[^?]*)\?(?<Encoding>\w)\?(?<Content>[^?]*)\?\=(?<Buttom>.*)?参考下...
      

  8.   


    按你的需求,换了种思路,看下是不是你要的结果吧
    //string test = "=?utf-8?Q?=E6=84=9F=E8=B0=A2=E6=82=A8=E5=9C=A8=E7=8C=AA=E5=85=AB=E6=88=92=E7=BD=91=E9=80=89=E5=AE=9A9698?==?utf-8?Q?=E5=8F=B7=E4=BB=BB=E5=8A=A1=E4=B8=AD=E6=A0=87=E4=BD=9C=E5=93=81=EF=BC=8C=E8=AF=B7=E7=A1=AE=E8=AE=A4=E4=BB=BB=E5=8A=A1=E5=AE=8C=E6=88=90=E3=80=82?=";
    //string test = "=?GB2312?B?vfHEv7HqobDT0brDxvPStaGxzNi/rw==?=";
    string test = "Yahoo! =?BIG5?B?wXC3+Q==?=: =?BIG5?B?p0Gkd7NRwdy90A==?=! =?BIG5?B?pd+nWaVbpEo=?= a717fe877 .";
    string Charset = "";
    string Encoding = "";
    string Content = "";
    Content = Regex.Replace(test, @"(\?=[^=]*)?=\?(?<Charset>[^?]*)\?(?<Encoding>\w)\?|\?=", delegate(Match m) { if (m.Groups["Charset"].Value.Trim() != "") { Charset = m.Groups["Charset"].Value; Encoding = m.Groups["Encoding"].Value; } return ""; });
    if (Charset != "")
    {
        richTextBox1.Text += Charset + "\n";
        richTextBox1.Text += Encoding + "\n";
        richTextBox1.Text += Content + "\n";
    }
    else
    {
        richTextBox1.Text += "匹配不成功!";
    }目前只能晚上上网,所以如果上面的不符合要求,或是又有新的形式,楼主记得给出你要的结果,否则我就只能靠猜了^o^
      

  9.   

    致 root_ 大侠: 
    大哥真乃神人也,对小弟的意图了解的一清二楚。
    您上面写的正则基本符合要求,只是我忘记说明一点,看如下字串:
    string test = "Yahoo! =?BIG5?B?wXC3+Q==?==?BIG5?B?p0Gkd7NRwdy90A==?=! =?BIG5?B?pd+nWaVbpEo=?= a717fe877 .";
    大哥看到了吗?每个编码的字串是以 =? 开始,以 ?= 结束,不在此中间的都是未编码的字串。您上面写的正则可以提取出首、尾未编码的字串,但中间的没有提取出来。未编码的字串已用红色标明。还有,您上面的结果是全部拼在一起的,这样无法解码,我需要如下的结果:定义解码函数:
    public static string DecodeText(string strText,string Charset,string Encoding)然后,用你的正则取得数据,应该是一个数组,其间有未编码的,也有已编码的,如果是已编码的,要提取出Charset 和 Encoding,然后,我会做如下处理:
    string Result
    for(,,)//这里是用正则提取到的数据
    {
    if(如果是未编码的数据)Result+=未编码的数据;
    if(如果是已编码的数据)Result+=DecodeText(已编码的数据,Charset,Encoding);//调用解码函数
    }
    return Result;
    当然也要兼顾到最标准的模式,即只有已编码的数据,且只有一段的,如 
    string test = "=?GB2312?B?vfHEv7HqobDT0brDxvPStaGxzNi/rw==?=";
    也有可能是我第二次提到的情况,即都已编码,但分段的,如 
    string test = "=?utf-8?Q?=E6=84=9F=E8=B0=A2=E6=82=A8=E5=9C=A8=E7=8C=AA=E5=85=AB=E6=88=92=E7=BD=91=E9=80=89=E5=AE=9A9698?==?utf-8?Q?=E5=8F=B7=E4=BB=BB=E5=8A=A1=E4=B8=AD=E6=A0=87=E4=BD=9C=E5=93=81=EF=BC=8C=E8=AF=B7=E7=A1=AE=E8=AE=A4=E4=BB=BB=E5=8A=A1=E5=AE=8C=E6=88=90=E3=80=82?=";
    也有这次提到的情况,即编码数据和未编码数据混杂,且多段。
    还有最简单的情况,即没有编码
    请大侠再次出手赐教,不胜感激。
      

  10.   

    哈,如此简单的一个问题,楼主要是早把具体需求说出来,应该早就解决了根本不用楼主考虑的那样复杂,做个替换就over了string[] test = new string[] { "=?utf-8?Q?=E6=84=9F=E8=B0=A2=E6=82=A8=E5=9C=A8=E7=8C=AA=E5=85=AB=E6=88=92=E7=BD=91=E9=80=89=E5=AE=9A9698?==?utf-8?Q?=E5=8F=B7=E4=BB=BB=E5=8A=A1=E4=B8=AD=E6=A0=87=E4=BD=9C=E5=93=81=EF=BC=8C=E8=AF=B7=E7=A1=AE=E8=AE=A4=E4=BB=BB=E5=8A=A1=E5=AE=8C=E6=88=90=E3=80=82?=", "=?GB2312?B?vfHEv7HqobDT0brDxvPStaGxzNi/rw==?=", "Yahoo! =?BIG5?B?wXC3+Q==?=: =?BIG5?B?p0Gkd7NRwdy90A==?=! =?BIG5?B?pd+nWaVbpEo=?= a717fe877 .", "only a test." };
    foreach (string s in test)
    {
        string result = Regex.Replace(s, @"\=\?(?<Charset>[^?]*)\?(?<Encoding>\w)\?(?<Content>[^?]*)\?\=", delegate(Match m) { return DecodeText(m.Groups["Content"].Value, m.Groups["Charset"].Value, m.Groups["Encoding"].Value); });
        richTextBox1.Text += result + "\n\n";
    }
    //输出:
    已解码已解码已解码Yahoo! 已解码: 已解码! 已解码 a717fe877 .only a test.不知道楼主解码函数的内容,我这里用下面的代替了
    public static string DecodeText(string strText, string Charset, string Encoding)
    {
        return "已解码";
    }楼主的问题,如果不算上解码函数的话,其实就一行代码而已
    string result = Regex.Replace(s, @"\=\?(?<Charset>[^?]*)\?(?<Encoding>\w)\?(?<Content>[^?]*)\?\=", delegate(Match m) { return DecodeText(m.Groups["Content"].Value, m.Groups["Charset"].Value, m.Groups["Encoding"].Value); });当然,上面写的正则默认为你的编码后的内容中没有“?”,如果可能存在,正则替换为
    string result = Regex.Replace(s, @"\=\?(?<Charset>[^?]*)\?(?<Encoding>\w)\?(?<Content>((?!\?\=)[\s\S])*)\?\=", delegate(Match m) { return DecodeText(m.Groups["Content"].Value, m.Groups["Charset"].Value, m.Groups["Encoding"].Value); });
    如果确认编码后的内容中不会存在“?”,那么就用前面的就可以了,后面这个会降低效率
      

  11.   

    致 root_ 大侠: 非常感谢您的帮助,对您的诲人不倦的态度,我永远会心存感激。这个问题已圆满解决了,下次如有问题,我会再次向您请教。再次对您高超的技术和乐于助人的精神致以谢意!