PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Regex-Wahnsinn in C#


anakin87
2009-03-09, 13:06:56
hey leute,
ich dreh mal wieder am rad wegen den ...-regex
und zwar steht in einem string ein html-code nachdem ich
das j-script da drinn ned brauch, hätt ich vorgehabt diese <script>*</script>
mit regex zu eliminieren. nur wie kann man sowas einstellen mit regex?
ich mein so:

Regex reg = new Regex("^<script>*</script>", RegexOptions.Multiline);
rext = reg.replace(text," ");

dürft es ja offensichtlich nicht gehen... aber wie geht das jetzt

jede hilfe wär da echt angesagt.... weil ich dreh durch :|

mfg

Gnafoo
2009-03-09, 13:31:13
Probier es einmal damit:


string foo = "test<script>abcde</script>test2<script>bla</script>";
foo = Regex.Replace(foo, "<script>.*?</script>", String.Empty);
Console.WriteLine(foo);


Der Stern heißt bei Regular Expressions einfach, dass das vorige Zeichen 0-n mal wiederholt werden darf. Du hast also gesucht nach "<script", gefolgt von 0-n ">", gefolgt von "</script>".

In meinem Beispiel steht da ein ".", was für ein beliebiges Zeichen steht. D.h. ".*" macht das, was du bei "*" erwartet hast. Das Fragezeichen dahinter bewirkt, dass er so wenige Zeichen wie möglich überspringt. Das verhindert, dass in meinem Beispiel erst das zweite "</script>" gematcht wird und damit auch das "test2" zwischen den zwei Skript-Blöcken verschwindet.

Edit: natürlich ist das in der Form nicht klug genug, mit <script> bzw. </script> in Kommentaren umzugehen. Aber vielleicht brauchst du das ja auch gar nicht.

Monger
2009-03-09, 13:40:18
Vielleicht bin ich ja grad auf dem Holzweg, aber wenn du einen Anchor in Kombination mit Multiline verwendest, heißt das für mich dass ^<script>.*?</script> nur matchen kann wenn der ganze Text tatsächlich auch mit dem script-tag anfängt, oder etwa nicht?

Das wird natürlich wahrscheinlich gar nicht matchen.

Gnafoo
2009-03-09, 13:49:04
Ich hab den Anchor ja gleich weggelassen. Denke auch, dass der eher unsinnig ist an der Stelle.

anakin87
2009-03-09, 13:57:33
weltklasse Gnafoo!!!!
funkt ich habs nur etwas anpassen müssen weil jeder die script-sequenz anders schreibt
groß/klein oder gleich direkt in den tag, usw.
aber so gehts bis jetzt

text = Regex.Replace(text, "<script>.*?</script>", " ",RegexOptions.IgnoreCase);
text = Regex.Replace(text, "<script.*?>.*?</script>", " ", RegexOptions.IgnoreCase);


nochmals thx @ all

kloffy
2009-03-09, 16:42:04
text = Regex.Replace(text, "<script>.*?</script>", " ",RegexOptions.IgnoreCase);
text = Regex.Replace(text, "<script.*?>.*?</script>", " ", RegexOptions.IgnoreCase);

Das der obere Fall im unteren enthalten ist ist dir bewusst?

anakin87
2009-03-09, 18:03:06
ups da hab ich einen teil vom auskomentierten testlauf mitgepostet...
aber es ist ja eh gleich aufgefallen ;D

anakin87
2009-03-10, 11:28:19
ach ja nochwas
warum ist dann

<SCRIPT LANGUAGE="JavaScript">blablabla</SCRIPT>
<SCRIPT LANGUAGE=JavaScript1.1>blablablablablabla</SCRIPT>

nicht dabei? weil so wies jetzt ist

text = Regex.Replace(text, "<script.*?>.*?</script>", " ", RegexOptions.IgnoreCase & RegexOptions.MultiLine);

erkennt er vieles nicht...
liegt es vl. daran das manchmal

<SCRIPT>blabla1</SCRIPT><SCRIPT LANGUAGE=JavaScript1.1>blabla2</SCRIPT>

aufeinander trifft?
mfg

Gast
2009-03-10, 13:47:42
Das liegt am fehlenden "RegexOptions.IgnoreCase". Dank dem bitweisen AND löschen sich die Flags gegenseitig aus und du übergibt effektiv 0 als Flags. Versuche es mal mit bitweisem OR -> "RegexOptions.IgnoreCase | RegexOptions.MultiLine".

anakin87
2009-03-10, 14:22:12
hm eigenartig...
gut ich hab jetzt als regex folgendes

text = Regex.Replace(text, "<script.*?/script>", " ", RegexOptions.IgnoreCase | RegexOptions.Multiline);

aber er lässt mir z.b das da über... obwohl dein tipp die erkennungsrate gesteigert hat...

<SCRIPT language="javascript" type="text/javascript">bla \n oder \t bla</SCRIPT>


wo liegt der fehler? ich bin fest der meinung das dieser fall auch in die regex fallen müsste...
ich befürcht irgendwie fast das das regex keine \n oder \t verträgt

mfg

kloffy
2009-03-10, 16:56:08
text = Regex.Replace(text, "<script.*?>[.\r\n\w]*?<\/script>", " ", RegexOptions.IgnoreCase | RegexOptions.Multiline);So?

anakin87
2009-03-11, 08:35:27
nicht ganz weil,
aus irgend einem grund spricht deins nicht an, aber dein system hat mir schon recht viel weiter geholfen
ich verwend jetzt das:

//das als regex liefert das selbe wie
<script.*[.\r\n\t]*.*/script>
//die regex -- an erkennungsraten und die sind relativ hoch
<script.*[.\n.\t.]*.*/script>

da spricht es immer noch nicht an.... warum? mag der keine ' oder " ?

//Reale-TestFall
<SCRIPT language="javascript" type="text/javascript">
var OAS_listpos = 'x01,Top,Right1,Middle1,Middle3,Top1,Middle2,Top1';
var OAS_sitepage = 'www.xyz.abc';
</SCRIPT>


ah ja ne frage warum .... <\/script>

mfg

Gast
2009-03-11, 12:01:37
ah ja ne frage warum .... <\/script>
Hab vergessen den Backslash rauszunehmen. Ich teste mit Regular Expression Calculator (http://www.codehouse.com/webmaster_tools/regex/), da braucht man den.

Noch ein Versuch:
text = Regex.Replace(text, "<script.*?>(.|\s)*?</script>", " ", RegexOptions.IgnoreCase | RegexOptions.Multiline);

anakin87
2009-03-11, 12:57:40
wie geil, wenn ichs vorher gewust hät dann hät ich dafür kein winform zum testen gebaut :D
die webversion is ah recht brauchbar....

hm funkt schon recht gut aber nicht perfekt ;) thx

ich hab die lösung gerade eben im netz gefunden - also wenn wer mal nen jscript-terminator braucht
hier der regex suchtext im c#-style

text = Regex.Replace(text, @"<script[^>]*>[\w|\t|\r|\W]*?</script>", " ", RegexOptions.IgnoreCase);

das "@" is nur weil .net oder c# die escape sequenzen nicht erkennt im string....

thx @ all ==> jetzt hab ich mal basiswissen für regex :D
mfg

Gnafoo
2009-03-11, 17:12:54
das "@" is nur weil .net oder c# die escape sequenzen nicht erkennt im string....
Eher anders herum. Der C#-Compiler wandelt die ihm bekannten Escape-Sequenzen (z. B. \n --> Newline) durchaus um. D. h. die entsprechende Methode der Regex-Klasse bekommt einen String, bei dem an der entsprechenden Stelle ein Newline und kein \n steht. Dann funktioniert aber deine Regex nicht wie gewollt, weil die Regex-Klasse die Escape-Sequenzen selber auswerten soll und stattdessen das schon umgewandelte Zeichen bekommt.

Abhilfe verschafft wie gesagt das @ vor dem String, welches die üblichen Escape-Sequenzen deaktiviert, oder ein doppelter Backslash an den entsprechenden Stellen. z. B. \\n.

anakin87
2009-03-12, 09:06:12
Eher anders herum. Der C#-Compiler wandelt die ihm bekannten Escape-Sequenzen (z. B. \n --> Newline) durchaus um. D. h. die entsprechende Methode der Regex-Klasse bekommt einen String, bei dem an der entsprechenden Stelle ein Newline und kein \n steht. Dann funktioniert aber deine Regex nicht wie gewollt, weil die Regex-Klasse die Escape-Sequenzen selber auswerten soll und stattdessen das schon umgewandelte Zeichen bekommt.

Abhilfe verschafft wie gesagt das @ vor dem String, welches die üblichen Escape-Sequenzen deaktiviert, oder ein doppelter Backslash an den entsprechenden Stellen. z. B. \\n.

ok hast mich.....
hab mal wieder blödsinn verzapft ;D..... sry,
laut galileo-computing:
Um die Interpretation als Escape-Sequenz für eine gegebene Zeichenfolge vollständig abzuschalten, wird vor der Zeichenfolge das Zeichen »@« gesetzt.
nun zum thema, warum gehts dann doch?
bzw. komischerweise gehen beide varianten, bin irgendwie verwirrt.....

text = Regex.Replace(text, "<script[^>]*>[\\w|\\t|\\r|\\W]*?</script>", " ", RegexOptions.IgnoreCase);
text = Regex.Replace(text, @"<script[^>]*>[\w|\t|\r|\W]*?</script>", " ", RegexOptions.IgnoreCase);



mfg