2010-08-07 31 views
1

表達我需要提取從串的數量和單元這樣經常用於匹配的數量和單元

1 tbsp 
1tbsp 
300ml 
300 ml 
10grams 
10 g 

的量將始終是數字,那麼有可能是或可能不是那麼空間內的單元。他們可能是15 - 它可能來自我們定義一個列表(可能是數組)

該解決方案可在20個不同的單位JavaScript或PHP,因爲我需要將它們存儲在數據庫中之前將它們分割。即它們需要分開存儲。

謝謝

編輯:對不起,很清楚。每一個新行代表一個新的字符串。這是該字符串將只包含10克或300毫升 - 所以我們只需要一次拆分一個單位和一個數量。

+0

他們會永遠在這樣的名單?或者有時會有其他文字? – hookedonwinter 2010-08-07 15:15:33

+0

@hookedonwinter - 只是自己。沒有其他文字。 – 32423hjh32423 2010-08-07 15:19:16

回答

4

好的,您可以做的是創建一個允許的單位數組,然後使用array_map在數組中的每個單位上應用preg_quote(這樣如果單位中有任何字符是正則表達式中的特殊字符它們將被轉義),然後構造一個正則表達式:

$units = array("tbsp", "ml", "g", "grams"); // add whatever other units are allowed 
$pattern = '/^(\d+)\s*(' . join("|", array_map("preg_quote", $units)) . ')$/'; 

$pattern將因此變得像/^(\d+)\s*(tbsp|ml|g|grams)$/,然後你可以用它來檢測的東西,看起來像你的串單位:

$matches = array(); 
// assuming you have an array of measurement strings... 
foreach ($measurement_strings as $measurement) 
{ 
    preg_match($pattern, $measurement, $matches); 
    list(, $quantity, $unit) = $matches; 
    // ... 
} 

由於該模式定義了兩個捕獲組,分別針對數量和單位,您可以從匹配中提取那些並按照您的要求進行操作。

(我更新了我的答案,根據問題更新,每行是一個單獨的字符串)。

+0

我認爲OP正在尋找更多這方面的知識,比如如何使用該模式來提取一系列匹配。 – hookedonwinter 2010-08-07 15:13:39

+0

@hookedonwinter我已經編輯了我的答案。 – 2010-08-07 15:27:54

+0

@大衛真棒!我喜歡隨時添加單位的能力。我認爲在正則表達式中有錯誤?代碼中的模式與解釋中的模式不同。 '$ /'vs'/ $'。試圖讓它在我的ide工作。但真棒迄今 – hookedonwinter 2010-08-07 15:34:58

4

正則表達式:

/(\d+)\s*(\D+)/ 

代碼:

preg_match_all('/(\d+)\s*(\D+)/', $ingredients, $m); 

$quantities = $m[1]; 
$units = array_map('trim', $m[2]); 

$quantities$units是:

Array 
(
    [0] => 1 
    [1] => 1 
    [2] => 300 
    [3] => 300 
    [4] => 10 
    [5] => 10 
) 
Array 
(
    [0] => tbsp 
    [1] => tbsp 
    [2] => ml 
    [3] => ml 
    [4] => grams 
    [5] => g 
) 

參見:http://ideone.com/MSH8t

如果你使用這個,你不必準備好一個單元列表。但是,這假設你的單位將沒有數字字符,而你的數量只是數字。

2

Mabye簡單的東西就夠了,就像這樣:

^([0-9]+)\s*([a-zA-Z]+)\s*$ 
+0

那些開始和結束錨點使它無法匹配多行 – quantumSoup 2010-08-07 15:32:24

+0

基本上,你是對的,但它也取決於實現。在c#中,您可以定義RegexOptions.Multiline,並且它正在開發多行代碼。例如new Regex(@「^([0-9] +)\ s *([a-zA-Z] +)\ s * $」,RegexOptions.Multiline)相當於new Regex(@「([0 -9] +)\ s *([a-zA-Z] +)\ s *「) – jwaliszko 2010-08-07 16:30:38

+0

@quantum:OP已更新問題,表示字符串將單獨處理,而不是多行文本塊,所以錨點應該不成問題。 – 2010-08-08 00:45:18