2013-07-10 59 views
2

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

检查这个字符串:

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?", ""); 
} 

你知道我失踪了吗?

+0

从我所看到的,你可以通过在空间上分割字符串来得到两个事件,对吧? – Jerry

+0

“windows-”和“?B?”之间的字符总是数字? –

回答

1

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

你需要使用一个非贪婪匹配

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

或排除?从你的角色

=\?[^?]*\?B\?[^?]*\?= 
+0

两个命题返回0比赛。 – CloudAnywhere

+0

+1为我工作 – Jerry

3

的列表当regexp解析器看到的.*字符序列,它匹配一切都交给字符串的结尾并返回,char by char(贪婪匹配)。因此,为避免此问题,您可以使用非贪婪匹配或明确定义可出现在字符串处的字符。

"=\?[a-zA-Z0-9?=-]*\?B\?[a-zA-Z0-9?=-]*\?=" 
+0

尝试...返回0匹配 – CloudAnywhere

+0

+1可能有点限制,但适用于给定的数据集 – Jerry

+0

是的!这个很好。我确认 – CloudAnywhere

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= 

请参阅this

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

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"); 
} 

Returns the same output

+0

当我解码一封电子邮件时,第一个字符串被编码,第二个字符串是“纯文本”。示例:=?Windows-1252?Q?Fr = E9d = E9ric_Gerard?= <[email protected]>。因此,应该只有一个匹配,即第一个将进入解码功能的字符串。正则表达式接合是最好的候选人提取仅编码模式 – CloudAnywhere

+0

@CloudAnywhere这个编码的字符串将不匹配,因为中间没有'?B?'。你是否想要匹配它?你有什么其他的可能性,或者只要它以'=?'开头并以'?='结尾并不重要? – Jerry

+0

是的,我不知道如何去一个新的行:-) – CloudAnywhere

相关问题