Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

drakon

Supermoderator

  • »drakon« ist der Autor dieses Themas

Beiträge: 6 513

Wohnort: Schweiz

Beruf: Entrepreneur

  • Private Nachricht senden

1

19.05.2011, 20:59

[Gelöst] Regex Ausschluss

Hi,

ich möchte einen Text, der manchmal HTML Tags für Links hat und manchmal nur die "www."-Variante hat in eine Form bringen, wo es nur HTML Tags hat.

Also z.B:

Quellcode

1
2
3
4
www.blubb.ch                                -> <a href="www.blubb.ch">www.blubb.ch</a>
<a href="www.blubb.ch">www.blubb.ch</a>     -> <a href="www.blubb.ch">www.blubb.ch</a>
<a href="www.blubb.ch">aaa</a>              -> <a href="www.blubb.ch">aaa</a>
<a href="...">asdf</a>www.blubb.ch          -> <a href="...">asdf</a> <a href="www.blubb.ch">www.blubb.ch</a>


Ich hatte das zuerst mit dem alleinigen Regex:

Quellcode

1
(http://)?www\\.\\S+\\.\\S+

Der macht dann allerdings bei den bereits existierenden Tags Unsinn.

Eine halbwegs akzeptable Variante habe ich, indem ich zuerst die korrekten Tags mit:

Quellcode

1
<a.*?href=\"(.*?)\">(.*?)</a>

entferne und dann mit dem obigen Regex nochmal drüber gehe. Dann habe ich allerdings das Problem, dass mir die ursprünglichen Linkinhalte verloren gehen.

Ich habe zwar bereits eine Idee, wie ich das umgehen kann, aber irgendwie wirkt mir das alles ein wenig zu fest gefrickelt. Hat da jemand eine bessere Idee?

Architekt

Community-Fossil

Beiträge: 2 481

Wohnort: Hamburg

Beruf: Student

  • Private Nachricht senden

2

19.05.2011, 21:59

Kombiniere doch beides in etwa dieser Form

Quellcode

1
(?:<a\s+href\s*\=\s*")?((?:http:\/\/)?www\..+?\.[a-z]+)(?:">)?\s*((?:http:\/\/)?www\..+?\.[a-z]+|[\w\-_]+)?(?:\s*<\/a>)?

Dann hast du in einen deiner beiden pattern deine URL und kannst das in die allgemeine form bringen und gleichzeitig das gesuchte komplett ersetzen.
Der einfachste Weg eine Kopie zu entfernen ist sie zu löschen.
- Stephan Schmidt -

drakon

Supermoderator

  • »drakon« ist der Autor dieses Themas

Beiträge: 6 513

Wohnort: Schweiz

Beruf: Entrepreneur

  • Private Nachricht senden

3

19.05.2011, 22:47

Kannst du den mal ein wenig mit Worten erläutern? Kenne deine Syntax nicht ganz.

Wie z.B handelst du das zweite Beispiel?

Architekt

Community-Fossil

Beiträge: 2 481

Wohnort: Hamburg

Beruf: Student

  • Private Nachricht senden

4

19.05.2011, 22:52

Welches zweite Beispiel meinst du genau?
Die Linkvariante? Oder die, wo als Linkname "aaa" angegeben ist.
Ich prüfe nur gleichzeitig ob schon eine HTML Variante vorliegt, extrahiere dann den entsprechenden Link und den -namen und du kannst es dann in die angemessene Form bringen.
Ist der Link in keiner HTML Form sondern liegt als (http://)www. form vor, extrahiere ich diese und du kannst damit auch machen was du möchtest.
Der einfachste Weg eine Kopie zu entfernen ist sie zu löschen.
- Stephan Schmidt -

drakon

Supermoderator

  • »drakon« ist der Autor dieses Themas

Beiträge: 6 513

Wohnort: Schweiz

Beruf: Entrepreneur

  • Private Nachricht senden

5

23.05.2011, 22:43

Das Problem war, dass ich das ganze in einem Ausdruck haben müsste und dann mit einem einheitlichen Ausdruck ersetzen kann. Ich habe dann eine Variante gebaut, die 4 läufe gebraucht hätte fand das dann aber zu komisch. Jetzt im Moment beisst sich ein Freund von mir auch gerade die Zähne daran aus. Ich habe in der Zwischenzeit das ganze von Hand gemacht: (Java)

C-/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
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
    public static String tidyLinks(String text)
    {   
        StringBuffer ret = new StringBuffer();
        
        StringBuffer link = new StringBuffer();
        boolean linkActive = false;
        char last = ' ';
        char preLast = ' ';
        char prepreLast = ' ';
        boolean aTagOpen = false;
        
        for(int i = 0; i < text.length(); ++i)
        {
            char current = text.charAt(i);
            
            if(current == 'a' && last == '<') // detect opening a tags "<a"
                aTagOpen = true;
            if(current == '>' && last == 'a' && preLast == '/' && prepreLast == '<') // detect closing a tags "</a>"
                aTagOpen = false;
            
            if(!aTagOpen) // do the replacement just if no a tag is opened
            {
                if(current == '.' && last == 'w' && preLast == 'w' && prepreLast == 'w')
                {
                    link.append("www");
                    linkActive = true;
                    
                    // remove already appended w's
                    ret.deleteCharAt(ret.length()-1);
                    ret.deleteCharAt(ret.length()-1);
                    ret.deleteCharAt(ret.length()-1);
                }
                
                if(linkActive)
                {
                    if(current == ' ' || i == text.length()-1) // end of link
                    {
                        linkActive = false;
                        if(i == text.length()-1 && current != ' ')
                            link.append(current);
                        
                        // append corrected version of link to return value
                        String plainLink = link.substring(0);
                        ret.append("<a href=\""+plainLink+"\">"+plainLink+"</a>");
                        if(current == ' ')
                            ret.append(current);
                        link = new StringBuffer();
                    }
                    else // gather link
                    {
                        link.append(current);
                    }
                }
                else // no link so just add it to the return value
                {
                    ret.append(current);
                }
            }
            else // an a tag is open so just append it
            {
                ret.append(current);
            }
            
            prepreLast = preLast;
            preLast = last;
            last = current;         
        }
        
        return ret.substring(0);
    }


Und hier wären noch ein paar Testcases, die akzeptiert werden müssen:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
        testCase("www.blubb.ch ","<a href=\"www.blubb.ch\">www.blubb.ch</a> ");
        
        testCase("<a href=\"\"></a>www.blubb.ch","<a href=\"\"></a><a href=\"www.blubb.ch\">www.blubb.ch</a>");
        
        testCase("<a href=\"\"></a><a href=\"www.blubb.ch\">www.blubb.ch</a>","<a href=\"\"></a><a href=\"www.blubb.ch\">www.blubb.ch</a>");
        
        testCase("<a href=\"\"></a><a href=\"www.blubb.ch\">aaa</a>","<a href=\"\"></a><a href=\"www.blubb.ch\">aaa</a>");
        
        testCase("ww.asfd.ch","ww.asfd.ch");
        
        testCase("www.a.ch www.b.ch","<a href=\"www.a.ch\">www.a.ch</a> <a href=\"www.b.ch\">www.b.ch</a>");
        
        testCase("ww www.b.ch","ww <a href=\"www.b.ch\">www.b.ch</a>");
    
        testCase("", "");   
        
        testCase("www.blubb.ch  ","<a href=\"www.blubb.ch\">www.blubb.ch</a>  ");
        
        testCase("www.blwwwubb.ch","<a href=\"www.blwwwubb.ch\">www.blwwwubb.ch</a>");
        
        testCase("www.asdf.ert.ch", "<a href=\"www.asdf.ert.ch\">www.asdf.ert.ch</a>");


Ist natürlich nicht ganz so elegant, wie Regex, aber ich bearbeite später lieber diesen Code nochmal, als eine 5 Zeilen langer Regex Ausdruck.

Wobei ich vermute, dass das in einem Regex Ausdruck gar nicht geht. Wenn mir jemand das Gegenteil beweisen will: Nur zu! ;)

Architekt

Community-Fossil

Beiträge: 2 481

Wohnort: Hamburg

Beruf: Student

  • Private Nachricht senden

6

23.05.2011, 22:52

Ich mach mich bestimmt total zum Affen, aber: was funktioniert an meinem obigen Regex nicht, so dass du das als Code lösen musst?
Der einfachste Weg eine Kopie zu entfernen ist sie zu löschen.
- Stephan Schmidt -

drakon

Supermoderator

  • »drakon« ist der Autor dieses Themas

Beiträge: 6 513

Wohnort: Schweiz

Beruf: Entrepreneur

  • Private Nachricht senden

7

23.05.2011, 23:47

Ich muss ehrlich sagen, dass ich deinen (ohne grösseren Aufwand) nicht ganz verstehe. Ich finde es recht schwer fremde Regexe zu lesen. ;)

Das Problem ist, dass ich einen ganzen Text habe und dort mit einem Ausdruck alle möglichen Fälle handhaben muss. Ich bin mir nicht sicher wie du das mit deinem machen willst. Es gibt ja keine Möglichkeit in der replaceAll Funktion Bedingungen anzugeben. Das detecten war weniger das Problem. Als viel mehr das nachherige korrekte ersetzen im Text.

Kann sein, dass mein Kollege und ich beide auf dem Schlauch stehen, aber wir haben das beide nach mehreren Stunden nicht hingekriegt, obwohl wir beide bereits einiges damit gemacht haben.

Aber du kannst es gerne mal mit den Testcases versuchen. (Links input, rechts was raus kommen sollte).

Architekt

Community-Fossil

Beiträge: 2 481

Wohnort: Hamburg

Beruf: Student

  • Private Nachricht senden

8

23.05.2011, 23:54

Mein Regex match sämtliche Vorkommnisse, ob in html tags oder als purer Link und speichert in einem Submatch die gefundene URL.
Danach dachte ich, nimmst du den Submatch und packst ihn in HTML Tags.
Aber ich glaub ich hab dich missverstanden und du wolltest so etwas gar nicht? Ansonsten werde ich morgen mal das gleiche in Java probieren, nur mit meinem Regex.
Text ist ja Äquivalent zu deinem Beispieltext im ersten Post nehme ich an?

Btw. Gratz zum 5000. Post :)
Der einfachste Weg eine Kopie zu entfernen ist sie zu löschen.
- Stephan Schmidt -

drakon

Supermoderator

  • »drakon« ist der Autor dieses Themas

Beiträge: 6 513

Wohnort: Schweiz

Beruf: Entrepreneur

  • Private Nachricht senden

9

24.05.2011, 00:29

Ich muss verschiedene Sachen machen (siehe testcases). Wenn ein purer link gefunden wird wird der verpackt. wenn ein bereits existierender gefunden wird soll der so bleiben (beachte, dass wenn im in einem a tag html links da sind die ebenfalls gelassen werden müssen).
Und das ganze muss dann in einem generischen replace Ausdruck gemacht werden. :)

btw:
Ich musste meinen obigen Code bereits anpassen. Gab sogar ein Link mit einem A Tag drin.. -.-'

Werbeanzeige