2012-05-13 18 views
6
$pattern = "/\[(.*?)\]\((.*?)\)/i"; 
$replace = "<a href=\"$2\" rel=\"nofollow\">$1</a>"; 
$text = "blah blah [LINK1](http://example.com) blah [LINK2](http://sub.example.com/) blah blah ?"; 
echo preg_replace($pattern, $replace, $text); 

Powyższe prace ale jeśli przestrzeń jest przypadkowo włożona pomiędzy [] i() przerwy wszystko i dwa łącza są zmieszane w jedno:Dlaczego jest mój regex PHP, który analizuje uszkodzone linki Markdown?

$text = "blah blah [LINK1] (http://example.com) blah [LINK2](http://sub.example.com/) blah blah ?"; 

Mam wrażenie, że to gwiazda laxy że łamie go ale nie wiem, jak dopasować powtarzające się linki.

+0

Czy to jakiś parser Markdown? Jeśli tak, dlaczego nie używasz już istniejącego? – Gumbo

+0

To jest. Potrzebuję tylko podstawowej funkcji łącza bez potrzeby podawania id i tytułu. – user1070125

Odpowiedz

7

Jeśli rozumiem cię, wszystko co trzeba zrobić naprawdę jest również dopasować dowolną liczbę przestrzeni między nimi, jak również, na przykład:

/\[([^]]*)\] *\(([^)]*)\)/i 

Objaśnienie:

\[    # Matches the opening square bracket (escaped) 
([^]]*)  # Captures any number of characters that aren't close square brackets 
\]    # Match close square bracket (escaped) 
*    # Match any number of spaces 
\(   # Match the opening bracket (escaped) 
([^)]*)  # Captures any number of characters that aren't close brackets 
\)    # Match the close bracket (escaped) 

Uzasadnienie:

I prawdopodobnie powinien uzasadnić, że powodem, dla którego zmieniono .*? do [^]]*

Druga wersja jest bardziej wydajna, ponieważ nie musi wykonywać dużej liczby operacji cofania, które wykonuje .*?. Dodatkowo, po napotkaniu otwarcia [, wersja .*? będzie dalej wyglądała, dopóki nie znajdzie dopasowania, zamiast niepowodzenia, jeśli nie jest tagiem, jak byśmy chcieli. Na przykład, jeśli pasuje do wyrażenia za pomocą .*? przeciw:

Sad face :[ blah [LINK1](http://sub.example.com/) blah 

będzie pasować

[ blah [LINK1] 

i

http://sub.example.com/ 

Stosując podejście [^]]* będzie oznaczać, że wejście jest dopasowane prawidłowo.

+0

Ten ma literówkę, ale nie mogę tego naprawić, ponieważ nie jestem pewien, jak to działa. – user1070125

+0

Masz rację, poprawiłem błąd i dodałem wyjaśnienie dla ciebie. – Jarmex

+0

Dodałem również uzasadnienie, dlaczego zmieniłem '. *?' Na '[^]] *' – Jarmex

0

Spróbuj tego:

$pattern = "/\[(.*?)\]\s?\((.*?)\)/i"; 

\s? dodany między \[(.*?)\] i \((.*?)\)

+0

To w jakiś sposób działa, zajmując się jedną przestrzenią. Myślę, że lepiej byłoby wymagać ścisłego oznaczania i ignorować wszystko inne (dane wyjściowe, jakie są). – user1070125

Powiązane problemy