2011-08-01 39 views
2

出於某種原因,下面的正則表達式這確實在.NET的工作不是在PHP工作:正則表達式不是在PHP工作一樣用C#

// Line breaks not in real expression, just for clarity here to show sub-expressions: 
$pattern = <<<REGEX 
    "(\\"|[^"])*" 
| 
    '(\\'|[^'])*' 
| 
    [A-Za-z_][A-Za-z_\-\d]* 
| 
    [\-\+]?\d+(\.\d+)? 
| 
    [=<>!][=] 
| 
    [?:,()*\/\-\+!] 
| 
    \|\|? 
| 
\&\&? 
REGEX; 

測試實際表達:

$pattern = '/"(\\\"|[^"])*"|\'(\\\'|[^\'])*\'|[A-Za-z_][A-Za-z_\-\d]*|[\-\+]?\d+(\.\d+)?|[=<>!][=]|[?:,()*\/\-\+!]|\|\|?|\&\&?/'; 

$expr = <<<EXPR 
something ? '<a href="example.com">', title, '</a>' : title 
EXPR; 

preg_match_all($pattern, $expr, $tokens); 

料到產出$tokens[0]

0: something 
1: ? 
2: '<a href="something.com">'  // Please note that ' are part of token! 
3: , 
4: title 
5: , 
6: '</a>' 
7: : 
8: title 

$tokens[0]

0: something 
1: ? 
2: a 
3: href 
4: something 
5: com 

出於某種原因,大部分輸入的缺失和文字的實際產量已被忽略。這在.NET中有效,但出於某種原因在PHP中不起作用。

+0

只是一個想法:如果你想提取你的DOM的一部分,使用像http://www.php.net/manual/en/domdocument.loadhtml.php可以讓你的生活更容易,當試圖提取信息。 – afuzzyllama

+0

@afuzzyllama它不用於分析標記,標記只是我自己的簡單表達式語言中的一個字符串。它用於數據綁定幷包含非常基本的語法。當令牌被硬編碼時,我的評估器工作正常,但正則表達式並沒有正確地分解輸入表達式。 –

+0

@afuzzyllama用評論更新了問題。撇號'實際上是所需字符串標記的一部分。 –

回答

2

問題是您需要轉義正則表達式反斜槓元字符。另外,最好用自由空間模式寫出複雜的正則表達式,並有很多註釋。這裏是你需要的PHP代碼:

<?php 
$pattern = '% 
     "(\\\\"|[^"])*"   # Either... a double quoted string, 
    |       # or... 
     \'(\\\\\'|[^\'])*\'  # a single quoted string, 
    |       # or... 
     [A-Za-z_][A-Za-z_\-\d]* # an identifier. 
    |       # or... 
     [\-\+]?\d+(\.\d+)?  # a number 
    |       # or... 
     [=<>!][=]    # a comparison operator, 
    |       # or... 
     [?:,()*\/\-\+!]   # a single char 
    |       # or... 
     \|\|?     # a logical or numerical OR 
    |       # or... 
    \&\&?      # a logical or numerical AND 
    %ix'; 

$expr = <<<EXPR 
something ? '<a href="example.com">', title, '</a>' : title 
EXPR; 

$a = preg_match_all($pattern, $expr, $tokens); 
print_r($tokens[0]); 

?> 

使用heredoc語法不需要或在這裏推薦。

+0

不知道這一點,謝謝我會用很多。是特定於PHP還是相當標準的自由間隔模式? –

+0

@Lea Hayes:是的,大多數(PHP,Java,Perl,Python,.NET)都有'x'模式 - 但不幸的是,JavaScript不會。 – ridgerunner

+0

再次感謝您的幫助。非常感謝 –

1

最後,到了那裏。它全部在$pattern的轉義序列中。不與定界符或'this type of literal'工作,但在"this type of literal"做工作:

$pattern = "/\"(\\\\\"|[^\"])*\"|'(\\\\'|[^'])*'|[A-Za-z_][A-Za-z_\\-\\d]*|[\\-\\+]?\\d+(\\.\\d+)?|[=<>!][=]|[?:,()*\\/\\-\\+!]|\\|\\|?|\\&\\&?/"; 

我會很好奇,看到一個工作版本定界符但正如我寧願避免模式本身內逃脫的那個討厭的水平。