2013-07-09 125 views
2

我想創建一個C#/ WPF解析器。我有正則表達式的良好的整體理解,因爲這不是我的第一個分析器(且可能不會是我最後一次)正則表達式奇怪的行爲

然而,現在我有一個很奇怪的行爲。這裏就是我試圖解析(注:實際數據刪除,我只是做了一個字符串遵循相同的結構,我的):

AAAAA BBBBB 50℃布拉布拉

我的應用程序將接收線我只是想分手並認出。出於某種原因,空格的數量是可變的(aaaa和bbbb之間的一個,bbbb和50之間的兩個)。 (注意之前人們告訴我:我不會使用string.Split()。因爲我有很多不同的線結構,我應該總是從中得到相同的數據,只是分開它會讓我無法識別什麼每個部分指)

我目前的測試正則表達式是有點簡單:

(\S*)[\s*](\S*)[\s*](\S*)[\s*](p|c)(.*) 

而現在,這裏是發生了什麼。如果僅僅是有一個空間betweet BBBBB和50,正則表達式正確分析(注:我用http://www.myregextester.com/index.php來測試我的正則表達式)

$matches Array: 
(
    [0] => Array 
     (
      [0] => aaaaa bbbbb 50 c blabla 
     ) 

    [1] => Array 
     (
      [0] => aaaaa 
     ) 

    [2] => Array 
     (
      [0] => bbbbb 
     ) 

    [3] => Array 
     (
      [0] => 50 
     ) 

    [4] => Array 
     (
      [0] => c 
     ) 

    [5] => Array 
     (
      [0] => blabla 
     ) 

) 

如果有兩個空格BBBB和50之間,會出現以下情況:

$matches Array: 
(
    [0] => Array 
     (
      [0] => bbbbb 50 c blabla 
     ) 

    [1] => Array 
     (
      [0] => bbbbb 
     ) 

    [2] => Array 
     (
      [0] => 
     ) 

    [3] => Array 
     (
      [0] => 50 
     ) 

    [4] => Array 
     (
      [0] => c 
     ) 

    [5] => Array 
     (
      [0] => blabla 
     ) 

) 

現在我知道我可以很容易地從行中刪除不需要的空間(這是我目前做的)。無論如何,我總是渴望理解我在那裏錯過了什麼:當我添加一個額外的空間時,爲什麼會發生這種情況,這應該通過我添加的[\ s *]之一來識別?

謝謝!

回答

5

[\s*]沒有做你期望的。方括號表示一個字符組,意思是它將匹配一個\s(空格)或*字符。

簡單地丟棄這些支架,以獲得預期的行爲:比賽\s(空格)0次或更多次:

(\S*)\s*(\S*)\s*(\S*)\s*(p|c)(.*) 

編輯:傑西的言論也是有價值的:除非一些羣體確實是可選的,你可能想使用+而不是*量詞。

+0

謝謝!我不知道我不能在方括號中使用*。至於明星們,現在肯定有太多的方法(儘管有些小組是可選的),我會盡可能地使用+。 – Damascus

+0

@Damascus這裏應該帶走的是正則表達式的語法是相當嚴格。這些方括號有非常明確的含義,你不能隨便換掉它們。當*放置在字符組中時,'*'不應該做任何特殊的事情,因爲字符組本身只會匹配*一個*字符。 –

2

您需要\s+更換[\s*]

[\s*]手段「要麼一個空白字符,或一個星號」。

\s+意味着「一個或多個空格字符」,這是你想要的。

Character classes的東西,所以很多人拿錯。

3

每當我看到正則表達式中的星星,我都會畏縮。星星匹配零或更多,並且可以真正把你絆倒!將*的所有實例替換爲+,然後重試。當然,除非這些分組中的某些確實是可選的。

編輯:其他的答案非常正確地指出,你使用的是字符組,但我的觀點依然存在:注意*

+0

您是絕對正確的。我從*開始,因爲如果有些團體是可選的,我不是在蘇爾,我很快就陷入了漩渦!我將離開*僅限可選組,謝謝! – Damascus

-2

[\ s *]具有不同的含義,因爲它位於方括號內[\ s] +會呈現您期望的行爲或[\ s] {1,}此表達式將匹配空白字符1次或更多次。您還需要記住,根據您使用的是什麼函數,您可能需要啓用作爲全局標誌的「g」標誌,以使您的正則表達式匹配您希望解析的所有出現的模式,否則它可能僅解析第一場比賽。括號會否定大多數字符類並將大多數修飾符轉化爲文字,除少數例外外,請訪問MDN https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions查看有關正則表達式在正則表達式中正則表達式如何在正則表達式內行爲的知識http://php.net/manual/en/reference.pcre.pattern.syntax.php