2013-06-22 16 views
7

Próbuję zrobić regex php, aby wyodrębnić wiele sekcji/warunków z jednego ciągu ... pozwól mi pokazać, o czym mówię; to jest fragment całkowitej zawartości plików (prawdziwe treść zawierać setki tych ugrupowań):php regex do wyodrębnienia wielu dopasowań ze stringów

part "C28" 
{ type  : "1AB010050093", 
    %cadtype : "1AB010050094", 
    shapeid : "2_1206", 
    descr  : "4700.0000 pFarad 10.00 % 100.0 - VE5-VS3", 
    insclass : "CP6A,CP6B", 
    gentype : "RECT_032_016_006", 
    machine : "SMT", 
    %package : "080450E", 
    %_item_number: "508", 
    %_Term_Seq : "" } 
part "C29" 
{ type  : "1AB008140029", 
    shapeid : "2_1206", 
    descr  : "150.0000 pFarad 5.00 % 100.0 Volt NP0 CERAMIC CAPACITOR", 
    insclass : "CP6A,CP6B", 
    gentype : "RECT_032_016_006", 
    machine : "SMT", 
    %package : "080450E", 
    %_item_number: "3", 
    %_Term_Seq : "" } 

Jak widać, dane zawarte w odpisie powtarza dwukrotnie. Muszę przeszukiwać całego pliku i wyodrębnić następujące elementy:

  • ciąg po słowie „część” - co byłoby „C28” lub „C29”
  • ciąg po „typu” nieruchomości - który byłby "1AB010050093" lub "1AB008140029"

Więc, w zasadzie, muszę pobrać wszystkie odnośniki do części i skojarzone typy z tego pliku ... i nie jestem pewien, jak najlepiej robiąc to.

Proszę dać mi znać, jeśli potrzebujesz więcej informacji, aby pomóc ... z góry dziękuję!

+0

Czy istnieje powód, dla którego nie używasz analizatora składni Json dla tego typu danych? –

+1

@Denomales Chociaż wygląda podobnie, przykład nie jest danymi JSON i nie działałby z 'json_decode' w PHP. –

+0

Wystarczająco fair. Musiałem zapytać. –

Odpowiedz

11

Opis

Wyrażenie to będzie:

  • przechwytywania nazwa grupy jako ref
  • przechwytywania wartości pól type i descr.
  • Pole Rodzaj gdy schwytany należy umieścić w nazwie grupy zwanej partnumber
  • Pola mogą być wyświetlane w dowolnej kolejności w organizmie
  • pole descr jest opcjonalny i powinny być zrobione tylko jeśli istnieje. Descr` pole (?: ... )?`` brackets around the sprawia, że ​​pole opcjonalne

Uwaga To jest pojedynczym wyrazem więc można by użyć opcji x tak aby silnik regex ignorować spacje.

^part\s"(?P<ref>[^"]*)"[^{]*{ 
(?:(?=[^}]*\sdescr\s*:\s+"(?P<descr>[^"]*)"))? 
(?=[^}]*\stype\s*:\s+"(?P<type>[^"]*)") 

enter image description here

kodu PHP przykład:

tekstu wejściowego

part "C28" 
{ type  : "1AB010050093", 
    %cadtype : "1AB010050094", 
    shapeid : "2_1206", 
    descr  : "4700.0000 pFarad 10.00 % 100.0 - VE5-VS3", 
    insclass : "CP6A,CP6B", 
    gentype : "RECT_032_016_006", 
    machine : "SMT", 
    %package : "080450E", 
    %_item_number: "508", 
    %_Term_Seq : "" } 
part "C29" 
{ type  : "1AB008140029", 
    shapeid : "2_1206", 
    descr  : "150.0000 pFarad 5.00 % 100.0 Volt NP0 CERAMIC CAPACITOR", 
    insclass : "CP6A,CP6B", 
    gentype : "RECT_032_016_006", 
    machine : "SMT", 
    %package : "080450E", 
    %_item_number: "3", 
    %_Term_Seq : "" } 
part "C30" 
{ type  : "1AB0081400 30", 
    shapeid : "2_1206 30", 
    insclass : "CP6A,CP6B 30", 
    gentype : "RECT_032_016_006 30", 
    machine : "SMT 30", 
    %package : "080450E 30 ", 
    %_item_number: "3 30 ", 
    %_Term_Seq : "30" } 

kod

<?php 
$sourcestring="your source string"; 
preg_match_all('/^part\s"(?P<ref>[^"]*)"[^{]*{ 
(?:(?=[^}]*\sdescr\s*:\s+"(?P<descr>[^"]*)"))? 
(?=[^}]*\stype\s*:\s+"(?P<partnumber>[^"]*)")/imsx',$sourcestring,$matches); 
echo "<pre>".print_r($matches,true); 
?> 

zestawienia

$matches Array: 
(
[ref] => Array 
    (
     [0] => C28 
     [1] => C29 
     [2] => C30 
    ) 

[descr] => Array 
    (
     [0] => 4700.0000 pFarad 10.00 % 100.0 - VE5-VS3 
     [1] => 150.0000 pFarad 5.00 % 100.0 Volt NP0 CERAMIC CAPACITOR 
     [2] => 
    ) 

[partnumber] => Array 
    (
     [0] => 1AB010050093 
     [1] => 1AB008140029 
     [2] => 1AB0081400 30 
    ) 

) 
+1

Naprawdę ładna odpowiedź! :) – hek2mgl

+0

Dziękuję bardzo :) –

+0

@Domomales skąd masz obraz wizualizacji regex? – tristanbailey

2

Zakładając, każda z tych grup ma taką samą strukturę, można użyć tego wzoru:

preg_match_all('~([^"]++)"[^{"]++[^"]++"([^"]++)~', $subject, $matches); 
print_r($matches); 

EDIT:

Wskazówka: jeśli masz więcej informacji wyodrębnić, możesz łatwo przekształcić swoje dane w json, na przykład:

$data = <<<LOD 
part "C28" 
{ type  : "1AB010050093", 
    %cadtype : "1AB010050094", 
    shapeid : "2_1206", 
    descr  : "4700.0000 pFarad 10.00 % 100.0 - VE5-VS3", 
    insclass : "CP6A,CP6B", 
    gentype : "RECT_032_016_006", 
    machine : "SMT", 
    %package : "080450E", 
    %_item_number: "508", 
    %_Term_Seq : "" } 
part "C29" 
{ type  : "1AB008140029", 
    shapeid : "2_1206", 
    descr  : "150.0000 pFarad 5.00 % 100.0 Volt NP0 CERAMIC CAPACITOR", 
    insclass : "CP6A,CP6B", 
    gentype : "RECT_032_016_006", 
    machine : "SMT", 
    %package : "080450E", 
    %_item_number: "3", 
    %_Term_Seq : "" } 
LOD; 
$trans = array("}\n" => '}, ' , 'part' => '' , 
       "\"\n{" => ':{"' , ':'  => '":' , 
       "\",\n" => '","'); 

$data = str_replace(array_keys($trans), $trans, $data); 
$data = preg_replace('~\s*+"\s*+~', '"', $data); 
$json_data =json_decode('{"'.substr($data,1).'}'); 

foreach ($json_data as $key=>$value) { 
    echo '<br/><br/>part: ' . $key . '<br/>type: ' . $value->type;  
}