2009-09-17 10 views
5

Próbuję zwrócić zawartość dowolnych tagów w treści tekstu. Obecnie używam następującego wyrażenia, ale przechwytuje tylko zawartość pierwszego znacznika i po nim ignoruje inne.Jak uzyskać wyrażenie regularne pasujące do wielu znaczników skryptu?

Oto próbka html:

<script type="text/javascript"> 
     alert('1'); 
    </script> 

    <div>Test</div> 

    <script type="text/javascript"> 
     alert('2'); 
    </script> 

Moje regex wygląda następująco:

//scripttext contains the sample 
re = /<script\b[^>]*>([\s\S]*?)<\/script>/gm; 
var scripts = re.exec(scripttext); 

Gdy uruchomię to na IE6, zwraca 2 mecze. Pierwszy zawierający pełny tag, drugi zawierający alert ("1").

Po uruchomieniu go na http://www.pagecolumn.com/tool/regtest.htm daje mi 2 wyniki, z których każdy zawiera tylko znaczniki skryptu.

+0

Czy rzeczywiście pisanie regex w javascript? Czy możesz dołączyć pasujący kod. – cdm9002

+0

Korzystanie z RegexBuddy 3.2.1, to działa dobrze. Przechwytuje zawartość obu tagów. – Phoexo

+0

Używam/gm. Zmodyfikowałem nieco wyrażenie regularne. Teraz zwraca 2 wyniki, z których każdy zawiera znacznik skryptu, ale zawiera również kod HTML. \t ] *> ([\ s \ S] *?) <\/script>/gm Jak mogę zwrócić tylko zawartość? – Geuis

Odpowiedz

28

"problem" Oto w jak exec prac. Dopasowuje tylko pierwsze wystąpienie, ale przechowuje bieżący indeks (tj. Pozycję karetki) we właściwości wyrażenia regularnego o wartości lastIndex. Aby uzyskać wszystkie mecze prostu zastosować regex ciąg aż nie pasuje (jest to dość popularny sposób to zrobić):

var scripttext = ' <script type="text/javascript">\nalert(\'1\');\n</script>\n\n<div>Test</div>\n\n<script type="text/javascript">\nalert(\'2\');\n</script>'; 

var re = /<script\b[^>]*>([\s\S]*?)<\/script>/gm; 

var match; 
while (match = re.exec(scripttext)) { 
    // full match is in match[0], whereas captured groups are in ...[1], ...[2], etc. 
    console.log(match[1]); 
} 
+3

Rozwiązuje to problem. – asdacap

+0

" alert (". Cholera, udaremniony ponownie! "); ' – Svante

+0

@Svante co z tym? :) – kangax

2

Spróbuj użyć globalną flagę:

document.body.innerHTML.match(/<script.*?>([\s\S]*?)<\/script>/gmi) 

Edit: dodano wiele linii i wielkość liter ma znaczenie Flagi (z oczywistych względów).

+0

lub, jeśli używasz funkcji regularnego wyewidencjonowania, upewnij się, że jest skonfigurowana tak, aby przechwytywać wszystkie dopasowania. Niektóre z nich wymagają wielu wywołań lub dodatkowego parametru lub funkcji różnicowej, która ma zostać wywołana. – TheJacobTaylor

+0

@TheJacobTaylor Wydaje się rodzaj niejasne. Co to jest funkcja regex, odwołując się do innego niż 'nowy RegExp'? –

+0

@Justin Johnson Mój komentarz był częściowo oparty na powyższych pytaniach dotyczących tego, w jakim języku był regex. Ponieważ nie byłam pewna, a oni osiągnęli rezultat, myślałem, że mogli na nie wpłynąć wywołując niewłaściwą funkcję. W PHP na przykład preg_match i preg_match_all zwrócą pierwsze lub wszystkie dopasowania. – TheJacobTaylor

0

Pierwsza grupa zawiera zawartość tagów.

Edycja: Czy nie musisz otaczać wyrażenia regularnego cytatami? Podobnie jak:

re = "/<script\b[^>]*>([\s\S]*?)<\/script>/gm"; 
+0

Nie, ty nie. W javascript, /.../ oznacza wyrażenie regularne. Jeśli chcesz, możesz go zbudować w postaci ciągu znaków, ale musisz wyraźnie określić jego konstrukcję. Np .: '/ ] *> ([\ s \ S] *?) <\/script>/g' jest równoważne z' nowym RegExp ("] *> ([\ s \ S] *?) <\/script>", "g") ' –

0

W .Net, istnieje metoda submatch, w PHP, preg_match_all, która powinna rozwiązać problem. W JavaScript nie ma takiej metody. Ale możesz zrobić samemu.

testowy w http://www.pagecolumn.com/tool/regtest.htm

Wybierz $ 1elements metody powróci co chcesz

3

nie wolno używać wyrażeń regularnych do parsowania HTML. HTML nie jest zwykłym językiem. Wykorzystaj moc DOM. Jest to o wiele łatwiejsze, ponieważ jest właściwym narzędziem.

var scripts = document.getElementsByTagName('script'); 
+0

Zawsze istnieje powód, aby ręcznie analizować dom z ciągów. IE8 usuwa znaczniki skryptów, jeśli na przykład spróbujesz użyć innerHTML. Jeśli buduję aplikację przy użyciu modułowych widgetów i szablonów html, staje się to problemem. – user2867288

+1

Czasami należy zdezynfekować łańcuch HTML przed przekształceniem go w DOM. –

+0

@ YuvalA .: dwie możliwości: 1. Jest nieprawidłowy HTML; następnie potrzebujesz "parsera zupy tagów". 2. To jest poprawny HTML; potrzebujesz parsera HTML. W każdym przypadku możesz użyć prostej składni zapytania po parsowaniu. – Svante

0

spróbować tej

for each(var x in document.getElementsByTagName('script'); 
    if (x && x.innerHTML){ 
      var yourRegex = /http:\/\/\.*\.com/g; 
      var matches = yourRegex.exec(x.innerHTML); 
      if (matches){ 
      your code 
}} 
+0

Istnieje już akceptowana odpowiedź na to pytanie, która spełnia to, co jest potrzebne. –

Powiązane problemy