3

我在查找字符串中出现的所有模式时遇到问题。

检查这个字符串:

string msg= "=?windows-1258?B?UkU6IFRyIDogUGxhbiBkZSBjb250aW51aXTpIGQnYWN0aXZpdOkgZGVz?= =?windows-1258?B?IHNlcnZldXJzIFdlYiBHb1ZveWFnZXN=?=";

我想返回 2 次出现(以便稍后解码它们):

=?windows-1258?B?UkU6IFRyIDogUGxhbiBkZSBjb250aW51aXTpIGQnYWN0aXZpdOkgZGVz?=

=?windows-1258?B?IHNlcnZldXJzIFdlYiBHb1ZveWFnZXN=?="

使用以下正则表达式代码,它仅返回 1 次:完整字符串。

var charSetOccurences = new Regex(@"=\?.*\?B\?.*\?=", RegexOptions.IgnoreCase);
var charSetMatches = charSetOccurences.Matches(input);
foreach (Match match in charSetMatches)
{
    charSet = match.Groups[0].Value.Replace("=?", "").Replace("?B?", "").Replace("?b?", "");
}

你知道我错过了什么吗?

4

3 回答 3

3

regexp解析器看到.*字符序列时,它会匹配直到字符串末尾的所有内容,然后逐个字符地返回(贪婪匹配)。因此,为避免该问题,您可以使用非贪婪匹配或明确定义可以出现在字符串中的字符。

"=\?[a-zA-Z0-9?=-]*\?B\?[a-zA-Z0-9?=-]*\?="
于 2013-07-10T19:05:43.360 回答
2

非正则表达式方式:

string msg= "=?windows-1258?B?UkU6IFRyIDogUGxhbiBkZSBjb250aW51aXTpIGQnYWN0aXZpdOkgZGVz?= =?windows-1258?B?IHNlcnZldXJzIFdlYiBHb1ZveWFnZXN=?=";
string[] charSetOccurences = msg.Split(new string[]{ " " }, StringSplitOptions.None);
foreach (string s in charSetOccurences)
{
    string charSet = s.Replace("=?", "").Replace("?B?", "").Replace("?b?", "");
    Console.WriteLine(charSet);
}

见一个ideone

如果你仍然想使用正则表达式,你应该.*通过添加一个?. 之前的用户已经提到了这一点,但是您似乎没有得到匹配?

string msg= "=?windows-1258?B?UkU6IFRyIDogUGxhbiBkZSBjb250aW51aXTpIGQnYWN0aXZpdOkgZGVz?= =?windows-1258?B?IHNlcnZldXJzIFdlYiBHb1ZveWFnZXN=?=";
var charSetOccurences = new Regex(@"=\?.*?\?B\?.*?\?=", RegexOptions.IgnoreCase);
var charSetMatches = charSetOccurences.Matches(msg);
foreach (Match match in charSetMatches)
{
    string charSet = match.Groups[0].Value.Replace("=?", "").Replace("?B?", "").Replace("?b?", "");
    Console.WriteLine(charSet);
}

见另一个ideone

两种情况下的输出是相同的:

windows-1258UkU6IFRyIDogUGxhbiBkZSBjb250aW51aXTpIGQnYWN0aXZpdOkgZGVz?=
windows-1258IHNlcnZldXJzIFdlYiBHb1ZveWFnZXN=

编辑:根据更新,查看针对您的问题的多合一解决方案

string msg= "=?windows-1258?B?UkU6IFRyIDogUGxhbiBkZSBjb250aW51aXTpIGQnYWN0aXZpdOkgZGVz?= =?windows-1258?B?IHNlcnZldXJzIFdlYiBHb1ZveWFnZXN=?=";
var charSetOccurences = new Regex(@"=\?.*?\?[BQ]\?.*?\?=", RegexOptions.IgnoreCase);
MatchCollection matches = charSetOccurences.Matches(msg);
foreach (Match match in matches)
{
    string[] encoding = match.Groups[0].Value.Split(new string[]{ "?" }, StringSplitOptions.None);
    string charSet = encoding[1];
    string encodeType = encoding[2];
    string encodedString = encoding[3];
    Console.WriteLine("Charset: " + charSet);
    Console.WriteLine("Encoding type: " + encodeType);
    Console.WriteLine("Encoded String: " + encodedString + "\n");
}

回报:

Charset: windows-1258
Encoding type: B
Encoded String: UkU6IFRyIDogUGxhbiBkZSBjb250aW51aXTpIGQnYWN0aXZpdOkgZGVz

Charset: windows-1258
Encoding type: B
Encoded String: IHNlcnZldXJzIFdlYiBHb1ZveWFnZXN=

看到这个

或者因为我们已经有了正则表达式,我们可以使用:

string msg= "=?windows-1258?B?UkU6IFRyIDogUGxhbiBkZSBjb250aW51aXTpIGQnYWN0aXZpdOkgZGVz?= =?windows-1258?B?IHNlcnZldXJzIFdlYiBHb1ZveWFnZXN=?=";
var charSetOccurences = new Regex(@"=\?(.*?)\?([BQ])\?(.*?)\?=", RegexOptions.IgnoreCase);
MatchCollection matches = charSetOccurences.Matches(msg);
foreach (Match match in matches)
{
    Console.WriteLine("Charset: " + match.Groups[1].Value);
    Console.WriteLine("Encoding type: " + match.Groups[2].Value);
    Console.WriteLine("Encoded String: " + match.Groups[3].Value + "\n");
}

返回相同的输出

于 2013-07-10T19:51:58.333 回答
1

.*是贪婪的,并且会匹配从第一个?到最后一个的所有内容?B?

您需要使用非贪婪匹配

=\?.*?\?B\?.*?\?=

?或从您的字符列表中排除

=\?[^?]*\?B\?[^?]*\?=
于 2013-07-10T19:01:03.677 回答