Entwickler-Ecke
C# - Die Sprache - php in C#
gordon65 - Sa 03.10.09 12:38
Titel: php in C#
Könnt ihr mir diesen php code in C# übersetzen
Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12:
| $pattern = '=^(.*)<a(.*)href\="?(\S+)"([^>]*)>(.*)</a>(.*)$=msi'; while (preg_match($pattern, $zeile, $txt)) { /* $txt[3] enthält die gewünschte URL. */ echo $txt[3]."\n"; /* $zeile neu bauen */ $zeile = $txt[1]." hier war mal ein Link ".$txt[6]; } /* $zeile zur Kontrolle ausgeben */ print "<br>".nl2br($zeile); |
(
http://php-faq.de/q-regexp-links-finden.html)
also ich will aus einer html datei alle links herausfiltern
Christian S. - Sa 03.10.09 12:49
Hallo und :welcome:!
Das Äquivalent zu preg_match findest Du in der Regex-Klasse wieder.
Dabei werden die Modifier nicht im regulären Ausdruck selber angegeben, sondern als zweiter Parameter im Konstruktor (hier: RegexOptions.Multiline | RegexOptions.Singleline | RegexOptions.IgnoreCase). Entsprechend brauchst Du auch keine Anfangs- und Endmarkierungen mehr im regulären Ausdruck (also die "="-Zeichen). Das braucht dann im regulären Ausdruck auch nicht mehr escaped werden.
Ich würde den Quelltext allerdings nicht so übernehmen, weil es IMHO nicht gerade elegant ist, jeden Fund im String durch einen anderen Text zu ersetzen, damit er nicht nochmals gefunden wird. In PHP sollte hier wohl eher preg_match_all verwendet werden, in C# dann entsprechend die Matches-Methode der Regex-Klasse.
Grüße
Christian
gordon65 - Sa 03.10.09 12:52
und jetzt nochmal alles in deutsch .... (bin eher noch anfänger)
kannst du mir vieleicht ein Beispiel machen ...
Christian S. - Sa 03.10.09 13:17
Hm, okay ;-)
Du hast diesen regulären Ausdruck:
$pattern = '=^(.*)<a(.*)href\="?(\S+)"([^>]*)>(.*)</a>(.*)$=msi';
Die von mir markierten Teile gehören nicht zum eigentlich Ausdruck. Das Gleichheitszeichen am Anfang gibt an, dass "=" Anfang und Ende des Ausdrucks markiert. Im zweiten markierten Bereich kommt erst das =-Zeichen (also die Endmarkierung) und dann kommen Modifier. "m" steht für Multiline, "s" für Singleline (hört sich erstmal widersprüchlich an, einmal kurz googlen wird Dir aber erklären, was die bedeuten), und "i" für IgnoreCase. Damit das "=" in der Mitte des Ausdrucks nicht als Ende erkannt wird, wird es mit einem "\" davor escaped.
Nun bei C#: Hier müssen Anfang und Ende nicht markiert werden, weil die Modifier nicht mit im String stehen. Der Ausdruck ist dann einfach der gesamte String, ohne irgendwelche Gleichheitszeichen oder Modifier. Pass aber auf, Du wirst Probleme mit den Anführungszeichen bekommen, weil die in C# ja auch einen String einleiten bzw. beenden. Ein regulärer Ausdruck wird in C# zum Beispiel so erstellt:
C#-Quelltext
1:
| var rx = new Regex("(.*?)", RegexOptions.IgnoreCase | RegexOptions.SingleLine); |
Die Schleife würde ich, wie gesagt, nicht so übernehmen. Die macht im Prinzip folgendes: Die sucht in einem Text nach einem Link. Wird dieser gefunden, wird der Link im Text durch "hier war mal ein Link" ersetzt und der Text wird erneut ganz von vorne durchsucht. Das ist absolut suboptimal. Viel sinnvoller wäre es ja, den Text von vorne bis hinten zu untersuchen und alle Links zu finden, ohne was zu ersetzen. Dazu muss man den Regex ein bisschen umändern, aber das überlasse ich erst einmal Dir ;-)
In C# macht man das so:
C#-Quelltext
1:
| var matches = rx.Matches(deinTextMitLinksDrin); |
Mit einer foreach-Schleife kannst Du dann die einzelnen Matches durchlaufen:
C#-Quelltext
1:
| foreach(Match m in matches) |
Jeder Match
m enthält ein Array mit den Unter-Matches (also in Deinem Regex oben wird ja z.B. die URL nochmal selber in einen Unter-Regex gepackt), abrufbar ist dieses Array über
m.Groups.
m.Groups[0] enthält den kompletten Regex,
m.Groups[1] den ersten Unter-Match usw.
Soooo, und zum Abschluss noch der Link zu einem kleinen aber IMHO sehr guten Tutorial zu Regexen:
http://tut.php-quake.net/de/regex.html Hier wird zwar wieder PHP verwendet, die regulären Ausdrücke funktionieren bis auf die Modifier aber identisch.
Grüße
Christian
gordon65 - Sa 03.10.09 14:47
also ich hab etwas rumprobiert aber irgendwie check ich das immer noch nicht.
Ich habe einen string in dem ist z.b der Quelltext einer Webseite gespeichert
und jetzt will ich haben das er mir den string durchsucht und mir die gefundenen Links in einer txt datei speichert.
kannst du mir richtig ein beispiel programmieren das auch umgefähr funktionieren würde
eigentlich bin ich ja noch dabei C# zu lernen, deshalb versteh ich das meiste noch nicht.
ich hoffe du machst dir die arbeit um das "noobgerecht" zu erklären (bzw. Als Beispiel darzustellst)
Christian S. - Sa 03.10.09 14:50
gordon65 hat folgendes geschrieben : |
| kannst du mir richtig ein beispiel programmieren das auch umgefähr funktionieren würde |
Sorry, nein, Du willst das Programm schreiben, nicht ich. ;-)
Zeig mal, wie Du es versucht hast und ich helfe Dir gerne an den Stellen weiter, wo es hakt. Mit den Hilfestellungen von oben und etwas Eigeninitiative sollte doch was da sein, wo man drauf aufbauen kann.
gordon65 - Sa 03.10.09 15:10
ok also
ich hab hier erst mal nochmal ein php beispiel das ich glaub ich besser verstehe
Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83:
| <?php
$link =array();
function suche_rekursiv($dateiname) { global $link; $i=1; // Geht in Datei und suche alle Links raus if($dateiname) { if ($handle = fopen ($dateiname, "r")) { while (!feof($handle)) { // Zeile für Zeile lesen $buffer = fgets($handle, 4096); // Links von navi_left preg_match("!<a class=\"dunkelgrau\".*?href=\"(.*?)\"[^>]*>(.*?)</a>!",$buffer, $treffer); if(!empty($treffer[1])) { // Links wie : " /news.php?link=0 " ergänzen mit -> http://www.wmdaten.de if(preg_match("#^\/#", $treffer[1])) { $treffer[1] = 'http://www.wmdaten.de'.$treffer[1]; if (!in_array($treffer[1], $link)) { $link[] = $treffer[1]; } $i++; } } } } } fclose ($handle); $raus = true; $merke[] = $dateiname ; // Neuen Dateinamen holen foreach($link as $nummer => $value ) { echo $nummer.': Link : '.$value.'<br>'; // hole neuen Dateinamen , geht in die Schleife nur einmal rein if($raus) { if($dateiname != $value) { // Neuer Dateiname $dateiname = $value; $raus=false; } } } echo 'Dateiname '.$dateiname.'<br>'; if (!in_array($dateiname, $merke)) { suche_rekursiv($dateiname); } }
// Aufruf der Funktion suche_rekursiv("http://www.wmdaten.de");
?> |
jetzt kommt mein code:
erst einmal öffne ich die txt datei mit dem quellcode:
C#-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38:
| using System; using System.Collections.Generic; using System.Linq; using System.IO; using System.Diagnostics; using System.Threading;
namespace link_öffner { class Program { static void Main(string[] args) {
StreamReader html = new StreamReader("html.txt");
string quelltext = html.ReadToEnd(); html.Close();
quelltext = new Regex |
also wie du siehst steck ich schon am Anfang fest ..
Christian S. - Sa 03.10.09 15:22
Das mit dem "var" ist mein Fehler, ich habe übersehen, dass Du angegeben hast, dass Du .NET 2.0 benutzt, da gibt es das noch nicht.
Die Quelltext heißen ohne das:
C#-Quelltext
1:
| Regex rx = new Regex("(.*?)", RegexOptions.IgnoreCase | RegexOptions.SingleLine); |
und
C#-Quelltext
1:
| MatchCollection matches = rx.Matches(deinTextMitLinksDrin); |
Jetzt zu Deinem Quelltext: Das mit dem Einlesen der Datei ist ja schonmal okay, wenn es auch über die File-Klasse schneller ginge. Aber wurscht, sieht erstmal okay aus.
Jetzt musst Du eine Instanz der Regex-Klasse erstellen, wie ich es oben demonstriert habe. Nur dass Du dann Deinen eigenen regulären Ausdruck dort reinschreiben musst und Du noch die korrekten Modifier eintragen musst (die stehen aber auch in einem meiner Postings).
Dabei ist es aber falsch, nochmals die
quelltext-Variable zu verwenden. Die hast Du ja als String deklariert und mit dem Quelltext befüllt, warum sollte da der reguläre Ausdruck rein? Lege für den eine neue Variable an.
Im übrigen verstehe ich unter Eigeninitiative auch, dass Du Dir mal die Doku zur Regex-Klasse anschaust. Da gibt's auch Beispiele zur Verwendung, auch zur Verwendung der Matches-Methode.
gordon65 - Sa 03.10.09 15:43
noch ein problem:
Sie haben gesagt das ich eine Instanz einer Regex-Klasse erstellen soll:
also Regex rx = new Regex(....);
dann sagt er mir aber
Fehler 1 Der Typ- oder Namespacename "Regex" konnte nicht gefunden werden. (Fehlt eine Using-Direktive oder ein Assemblyverweis?)
????
Christian S. - Sa 03.10.09 15:49
Hallo!
Die Fehlermeldung enthält schon die Lösung ;-) Es fehlt eine entsprechende Using-Direktive, weil die Regex-Klasse im Namespace "System.Text.RegularExpressions" liegt. *hust* Dokumentation *hust*
Wenn Du mal den Cursor in das Wort "RegEx" im Visual-Studio-Editor setzt, erscheint da so ein ... Ding ;-) ... gennannt "SmartTag" am Wort. Wenn Du da drauf klickst, gibt es die Option, die using-Direktive automatisch einzufügen.
Grüße
Christian
P.S.: Wir duzen uns hier ;-)
gordon65 - Sa 03.10.09 16:13
C#-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30:
| using System; using System.Collections.Generic; using System.Linq; using System.IO; using System.Diagnostics; using System.Threading; using System.Text.RegularExpressions;
namespace link_öffner { class Program { static void Main(string[] args) {
StreamReader html = new StreamReader("html.txt");
string quelltext = html.ReadToEnd(); html.Close();
Regex rx = new Regex("(.*?)", RegexOptions.IgnoreCase | RegexOptions.Singleline);
MatchCollection matches = rx.Matches(quelltext); |
also das ist also mein neuer ...
ich hab mir die dokumentation von regex angeschaut .. hab es aber immer noch nicht so richtig verstanden da es auch eher in php ist ...
also bei new Regex("(.*?)", RegexOptions.IgnoreCase | RegexOptions.Singleline);
kommt doch in den klammern rein nach was er suchen soll oder ???
wie geht es jetzt weiter ... die ergebnisse sind doch jetzt in "matches" drinnern oder ???
wie verarbeite ich die jetzt weiter
Christian S. - Sa 03.10.09 16:16
gordon65 hat folgendes geschrieben : |
| wie verarbeite ich die jetzt weiter |
Siehe mein Posting weiter oben ... Schleife und so Zeug.
In der Dokumentation (also der, die beim Visual Studio dabei ist), ist auch dazu ein Beispiel.
Irgendwie vergeht mir langsam die Lust ...
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2026 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!