2014-06-12 17 views
6

Jestem bardzo nowy w obu stackoverflow i Regexes, więc proszę wybacz błędy.Regex wykrywa wszystko, co nie pomiędzy {}, a następnie przeszukuje od tego, co pasuje

Szukałem dokładnie dla Regex, aby dopasować cały tekst, który nie jest pomiędzy nawiasami klamrowymi {} i od tego tekstu znaleźć pewne słowa. Na przykład od następujący ciąg:

$content = 'Hello world, { this } is a string with { curly brackets } and this is for testing'

Chciałbym poszukiwania wyrazu this wrócić tylko drugie wystąpienie this ponieważ ITS w obszarze, który nie jest w nawiasach klamrowych. Nawet jeśli mogę uzyskać Regex, aby dopasować podciągi poza nawiasami klamrowymi, rzeczy się upraszczają. Znalazłem ten Regex /(}([^}]*){)/, ale nie można wybrać części Hello world, i and this is for testing, ponieważ nie są one wewnątrz }{ i tylko wybiera część is a string with.

Chciałbym również zapytać, czy możliwe jest połączenie dwóch Regexów w jednym celu, takim jak mój. Na przykład pierwszy Regex znajdzie ciągi poza {}, a drugi znajdzie konkretne słowa, które są wyszukiwane.

Chcę użyć tego Regeksu w php i na razie używam funkcji, która jest bardziej jak hack. Celem jest znalezienie specyficznych słów, które nie są w {}, zastąpić je niezawodnie i pisać do plików tekstowych.

Z góry dziękuję za pomoc.

Odpowiedz

5

(SKIP *) (* F)

Masz szczęście, jak silnik PCRE regex PHP ma składnię, który jest wspaniały dla tego rodzaju zadania. Ten schludny praca regex jak czar (patrz demo):

{[^{}]*}(*SKIP)(*F)|\bthis\b 

Ok, ale jak to działa?

Cieszę się, że zapytał. Lewa strona alternatywy | dopasowuje kompletnie {braces}, a następnie celowo się zawiesza, po czym silnik przeskakuje do następnej pozycji w łańcuchu. Po prawej stronie spełniających this słowa chcesz, i wiemy, że są te właściwe, ponieważ nie były one dopasowane przez wyrażenie po lewej stronie ...

Jak używać go w PHP

tylko zwykle, coś jak:

$regex = "~{[^{}]*}(*SKIP)(*F)|\bthis\b~"; 
$count = preg_match_all($regex,$string,$matches); 

będziemy chcieli przyjrzeć się $matches[0]

dalszego czytania o tym i podobnym e Techniki xclusion

Ta sytuacja jest bardzo podobna do tej kwestii o "regex-matching a pattern unless...", która, jeśli jesteś zainteresowany i cieszył (*SKIP) moc, może chcesz przeczytać, aby w pełni zrozumieć technikę i jak może zostać przedłużony.

+0

To działa idealnie. Wiedziałem, że musi istnieć coś takiego (* SKIP) (* F), ale po prostu o tym nie wiedziałem. I dziwnie nie ma jeszcze podobnego pytania na temat stackoverflow. Przynajmniej nie mogłem go znaleźć. Dzięki – Shark

+0

@Shark Dzięki, cieszę się, że Ci się podoba! :) Cześć, widzę, że jeszcze nie głosowałeś na StackOverflow. Aby uzyskać jakąkolwiek pomocną odpowiedź, rozważ głosowanie, ponieważ tak działa system reputacji. Bez zobowiązań, oczywiście! Dziękuję za wysłuchanie mojego 10-sekundowego samouczka SO Rep. :) – zx81

+1

@Shark Btw znajdziesz inne pytania SO z tą techniką, ale tak, może nie na górze Google. Aby zapoznać się z całą historią, polecam zapoznać się z [połączonym pytaniem] (http://stackoverflow.com/questions/23589174/match-or-replace-a-pattern-except-in-situations-s1-s2-s3 -etc/23589204 # 23589204), lub zapisać go na później, miałem dużo zabawy, pisząc odpowiedź. :) – zx81

0

z łańcuchami nie bardzo długo, będę używać prostych funkcji ciąg manipulacji, aby je przeszukiwać

$content = 'Hello world, { this } is a string with { curly brackets } and this is for testing'; 

function searchify($stack,$charStart='{',$charEnd='}') { 
    $searchArea = ''; 
    $first = explode($charStart,$stack); 
    foreach ($first as $string) { 
    list($void,$ok) = (strpos($string,$charEnd) ? explode($charEnd,$string) : array('',$string)); 
    $searchArea.= $ok; 
    } 
    return $searchArea; 
} 

to zwraca ciąg wyczyszczone, a następnie strtr ...

$replacing = array 
('with'=>'this', 
    "\n"=>'<br>', 
    ' '=>"<br>",); 
$raw = searchify($content); 
$replaced = strtr($raw,$replacing); 
var_dump($replaced); 

... aby zastąpić w nim wartości.

+0

Postaram się odpowiedzieć później dzisiaj. Zastanawiam się, który jest szybszy, Regex z Preg_replace(), czy twoja funkcja z str_replace? Tak jak wspomniałem w pytaniu, moim celem jest zastąpienie wszystkich takich dopasowań długimi łańcuchami. Natomiast wyrażenie regularne używające \ bword \ b do dzielenia wyrazów i wstawiania w preg_replace wydaje się idealne jako rozwiązanie jednoliniowe. – Shark

+0

Wierzę, że najszybsze będą prawdopodobnie wyrazy regularne, choć to jest łatwo zaimplementowane. Jak długie są twoje struny? –

+0

Struny są mniej więcej takie same jak moje pytanie lub więcej. – Shark

Powiązane problemy