2012-01-04 65 views
1

我想匹配單個或雙引號標記,之後是不只是匹配的字符的字符中的任意量,隨後的字符中的一個相匹配:正則表達式後面參考負先行原子團

"--'__'--" 

應該在每一端使用雙引號。不過,我想這場比賽是在那些已經經過測試不應該包括在未來的任何字符佔有慾匹配:

"--'__'-- 

應該匹配,因爲在開始的雙引號從不之後另一個在最後。我想出了:

(?P<q>['"])(?>((?!(?P=q)).)*)(?P=q) 

但是,這仍然在中間的單引號匹配上面我的第二個字符串的例子。我不明白爲什麼原子團體沒有完成這個。我還沒有能夠用任何其他的原子分組安排來實現這一點。

另外,如果有可能,在所有在引號之間,同時聲明,該報價存在,這將是極好只匹配的字符。因爲向後斷言是固定寬度我不能使用一回參考斷言是單引號或雙引號的拍攝組之前的負先行發生。

+0

是你的投入僅包括這些或有什麼事嗎?有沒有理由爲什麼你的正則表達式不被錨定? – fge 2012-01-04 10:53:33

+0

@fge好點。這可能會成爲更大的表達的一部分,除非我最終將所有事情都分解成更小的子表達式。我沒有太多的正則表達式,並且我不太確定在這裏如何使用錨。開始的錨會確保它不會像我的第二個字符串那樣「匹配中間」嗎?如果這個表達式在輸入開始時不匹配,那麼這是如何改變的? – taz 2012-01-04 10:59:51

+0

那麼,線路錨點的開始確保匹配確實只能在一開始就發生。你可以嘗試在開頭添加一個'^',看看它的行爲如何? – fge 2012-01-04 11:02:28

回答

0

假設將有每行僅有一個有效報價子,這可能是一個很好的起點:

<?php // test.php Rev:20120105_1800 
// Return array of valid quoted substrings, one per line. 
function getArrayOfOnePerLineValidQuotedSubstrings($text) { 
    $re = '% 
     # Match line w/1 valid "single" or "double" substring. 
     ^    # Anchor to start of line. 
     [^\'"]*   # Everything up to first quote. 
     (?|    # Branch reset group $1: Contents. 
      "([^"]*)"  # Either $1.1 Double quoted, 
     | \'([^\']*)\' # or $1.2 Single quoted contents. 
     )    # End $1: branch reset group. 
     [^\'"]*   # Everything after quoted sub-string. 
     $    # Anchor to end of line. 
     %xm'; 
    if (preg_match_all($re, $text, $matches)) { 
     return $matches[1]; 
    } 
    return array(); 
} 
// Fetch test data from file. 
$data = file_get_contents('testdata.txt'); 
// Get array of valid quoted substrings, one per line. 
$output = getArrayOfOnePerLineValidQuotedSubstrings($data); 
// Display results. 
$count = count($output); 
printf("%d matches found.\n", $count); 
for ($i = 0; $i < $count; ++$i) { 
    printf(" match[%d] = {%s}\n", $i + 1, $output[$i]); 
} 
?> 

此正則表達式包含一個有效的引用串並跳過具有無效行(每行相匹配即"--'__'--其中有一個不平衡的雙引號子字符串)或沒有引用的子字符串。對於匹配的行,有效的帶引號的子字符串的內容返回組$1。該函數返回匹配的子串的數組。

如果您的數據將每行包含多個子串,或者如果引用子之間的報價子或東西可能包含轉義引號,那麼一個更復雜的解決方案可以配製。