2013-07-10 116 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

相關問題