2013-07-30 82 views
4

我有形式簡單的regex Befuddlement

string strA = "Cmd:param1:'C:\\SomePath\SomeFileName.ext':param2"; 
string strB = "Cmd:'C:\\SomePath\SomeFileName.ext':param2:param3"; 

我想拆就這個字符串的一些字符串「:」這樣我就可以提取的N個參數。有些參數可以包含文件路徑[如顯式]所示,我不想在括號內的':'上進行分割。我可以用一個正則表達式來做這件事,但我很困惑如何在冒號兩邊都沒有「'」的情況下才能分解正則表達式。

我試圖

string regex = @"(?<!'):(?!')"; 
string regex = @"(?<!'(?=')):"; 

是繼續匹配,只有在沒有「「」在左,沒有「」」右邊(後面/前面負的樣子),但是這仍然是在分裂包含在'C:\ SomePath \ SomeFileName.ext'中的冒號。

如何根據需要修改此正則表達式?

謝謝你的時間。


注:我發現以下的正則表達式的工作。然而,我想知道是否有更好的方法來做到這一點?

string regex = @"(?<!.*'.*):|:(?!.*'.*)"; 
+2

使用單引號分隔Windows路徑並不像使用雙引號那麼聰明;單引號是路徑中的合法字符,而雙引號不是,因此使用雙引號(即使它們必須被轉義)會使解析起來更容易。 – JAB

+0

@JAB你絕對是對的,但與大多數事情一樣,這是一個遺留物,我留下來處理從許多衛星以前做出的設計決定... – MoonKnight

回答

2

考慮使用此方法:

var guid = Guid.NewGuid().ToString(); 
var r = Regex.Replace(strA, @"'.*'", m => 
{ 
    return m.Value.Replace(":", guid); 
}) 
.Split(':') 
.Select(s => s.Replace(guid, ":")) 
.ToList(); 
+1

我非常喜歡這個。我沒有使用過甚至碰到過「Guid」類。頂部頂部的工作,並感謝您的時間... – MoonKnight

1

,而不是試圖構建一個回顧後發正則表達式來分割上,你可以構造一個正則表達式匹配字段本身並採取一套匹配正則表達式。 EG一個字段是不報價的報價序列(即可以包括:),也可以不包括分離器:

string regex = "'[^']*'|[^':]*"; 
var result = Regex.Matches(strA, regex); 
+0

這將返回冒號和_not_我的參數... – MoonKnight

+1

你不需要第一個'[^']',非貪婪的匹配工作也很好。 ''''。*''[['':] *'。(當然,不用考慮路徑中有單引號的可能性,但是由於Killercam系統顯然是預先存在的設計決策,所以希望禁止。) – JAB

+0

@Killercam它應該匹配你的參數,而不是冒號。他是匹配的,而不是分裂的。 – JAB

1

你想拆就(?<!\b[a-z]):(?!\\)(使用RegexOptions.IgnoreCase)。

+0

感謝您的時間。 – MoonKnight

+0

我不確定評論的含義。作品?不起作用? – Tomalak

+0

它的工作原理,我只是感謝你花時間回答... – MoonKnight

1

不盡如人意,但您可以用安全字符替換:\,然後在拆分後將它們返回到:\

string[] param = strA.Replace(@":\", "|||").Split(':').Select(x => x.Replace("|||", @":\")).ToArray(); 
+0

+1固體選項。謝謝你的時間... – MoonKnight