2014-03-03 39 views
0

美好的一天。 我有一個正則表達式的問題,我真的卡住了,問題是,我想提取字段可以像組成:使用可選模式複雜化正則表達式

NULL 

Name#Size^Value#XXL^Quantity#3 

Name#Size^Value#S^Name#Color^Value#Black^Quantity#2 

大小將永遠是第一位,顏色(可選)第二個值,最後一個數量。 當然,我想獲得這些值插入到數據庫中。

其實我已經這樣做了:

$txt='Name#Size^Value#S^Name#Color^Value#Black^Quantity#2'; 

    $re1='(Name#Size\\^Value#)'; 
    $re2='((?:[a-z][a-z0-9_]*))'; 
    $re3='(\\^Name#Color\\^Value#)'; 
    $re4='((?:[a-z][a-z0-9_]*))'; 
    $re5='(\\^Quantity#)';  
    $re6='(\\d+)';  

    if ($c=preg_match_all ("/".$re1.$re2.$re3.$re4.$re5.$re6."/is", $txt, $matches)) 
    { 
     $word1=$matches[1][0];  
     $var1=$matches[2][0]; 
     $word2=$matches[3][0]; 
     $var2=$matches[4][0]; 
     $word3=$matches[5][0]; 
     $int1=$matches[6][0]; 
     print "<br> Size: $var1 <br> Color: $var2 <br> Quantity: $int1"; 
    } 

,但我不知道我如何能匹配的顏色可選(在這種情況下,把數量作爲第二個參數

任何人都可以。幫我在這? 它應該是完全錯誤的。在這種情況下,請點我好的方向發展。

+0

爲什麼*尺寸*和*顏色*每有一個'Name'和'Value'場,但*數量*不? – simbabque

+0

這是問題之一,我對字符串本身有任何控制權,並且以這種奇怪的方式構建:/ –

+1

請參閱我的回答,以獲取不使用複雜正則表達式的簡單方法。 – simbabque

回答

1

沒有必要用正則表達式來做到這一點。您可以根據一些規則將字符串拆分兩次,從而輕鬆解決問題。

更新:這是php代碼。將在沒有單個正則表達式的情況下工作,也可以用於這些屬性的更復雜組合。

function split_string($string) { 
    $properties = Array(); 
    $pairs = explode('^', $string); 
    while ($pairs) { 
    $first_pair = split('#', array_shift($pairs)); 
    if ($first_pair[0] == 'Name') { 
     $second_pair = split('#', array_shift($pairs)); 
     $properties[$first_pair[1]] = $second_pair[1]; 
    } else { 
     $properties[$first_pair[0]] = $first_pair[1]; 
    } 
    } 
    return $properties; 
} 

print_r(split_string("Name#Size^Value#S^Name#Color^Value#Black^Quantity#2")); 
print_r(split_string("Name#Size^Value#XXL^Quantity#3")); 

輸出:

Array 
(
    [Size] => S 
    [Color] => Black 
    [Quantity] => 2 
) 
Array 
(
    [Size] => XXL 
    [Quantity] => 3 
) 
+0

我在Perl中編寫了這個代碼,並且直接將其翻譯爲PHP。也許這可以使我不知道的PHP成語更優雅。 – simbabque

+0

真的很好的方法我確實給它一個(和測試)謝謝! :D –

+1

我的確需要學習perl。 –

2

添加?在顏色的正則表達式的結束顏色可選匹配

+0

like:(\\^Name#Color \\^Value#?) –

+2

這隻會使最後一個'#'可選。你需要它在括號之外。 '(富)?'。 – simbabque

2

什麼東西大幅度簡單的是這樣的:

(?:name#(\w+?)\^)?(?:value#(\w+?)\^)?(?:quantity#(\d+?))? 

http://regex101.com/r/nN4yT3

由於您的最後一位(數量)不遵循的模式,它結束了一下第二擷取組愚蠢的;在這方面,可能更容易使用命名捕獲組:

(?:name#(?<name>\w+?)\^)?(?:value#(?<value>\w+?)\^)?(?:quantity#(?<quantity>\d+?))? 
+0

我必須測試它,聽起來真的更簡單,但我從來沒有使用之前... –

+1

如果你去路線,你可以通過名稱'$ matches ['name']'引用它們。 – brandonscript

+0

真的很有用,像它一樣 –

0

只需要選購的量詞(如別人說的)。
但是,它可能會保持更好,因爲 -
(注意 - 我不是一個PHP大師)

$re = 
'/ 
    Name\#Size\^Value\# 
    ([a-z] [a-z0-9_]*)    # (1) 
    \^Name\#Color\^Value\# 
    ([a-z] [a-z0-9_]*)?    # (2) 
    \^Quantity\# 
    (\d+)       # (3) 
/xi'; 

if (preg_match_all ($re, $txt, $matches)) 
{ 
     $var1 = $matches[1][0]; 
     $var2 = $matches[2][0]; 
     $var3 = $matches[3][0]; 
     print "<br> Size: $var1 <br> Color: $var2 <br> Quantity: $var3"; 
}