Keywords nur einmal verlinken


jimb0p

Erfahrenes Mitglied
#1
Hallo Zusammen,

ich habe einen String von beliebig vielen Wörtern. In diesem String möchte ich bestimmte Keywörter ersetzen durch Links. Bsp: "Lorem ipsum dolor sit amet, consetetur sadipscing" soll das Keyword 'dolor sit' verlinkt werden. Ergibt also "Lorem ipsum <a href="http://blabla.com">dolor sit</a> amet, consetetur sadipscing". Das nächste Keyword ist nur 'dolor' dies soll nun aber nicht mehr an dieser Stelle verlinken da es dann ja doppelt verlinkt ist, aber ggf. im weiteren Text nochmal vorkommt. Die Keywordliste ist auch beliebig lang, jedoch linken die Keywordgruppen je auf ein und die selbe URL und wenn diese URL 3x benutzt wurde dann soll nicht weiter verlinkt werden.

Der Knackpunkt bei mir ist jedoch das nicht doppelt verlinken. Wenn jemand eine Idee hat wäre stark!
Gruß!
 
#2
Hi

wie wird entschieden, ob "dolor" oder "dolor sit" besser ist?
Gibt es eine Rangordnung der Keywords?
Sind längere Ausdrücke besser?
...?

Wenn "dolor sit" genommen wird, darf also ein späteres "dolor" trotzdem auch verlinkt werden,
und ggf. bis zu zwei weitere "dolor sit"?
 
#4
Hast gerade zu schnell geantwortet :) (oder ich zu langsam geschrieben :D)
Auszug von meiner Bearbeitung oben:

Wenn "dolor sit" genommen wird, darf also ein späteres "dolor" trotzdem auch verlinkt werden,
und ggf. bis zu zwei weitere "dolor sit"?

(bin so halb fertig mit einem größeren "Lösungs"-Beitrag,
den ich aber vermutlich erst am Abend fertigschreiben kann)
 
Zuletzt bearbeitet:
#6
Am einfachsten wäre es, die Keys durchzugehen - dabei die langen zuerst - und durch Platzhalter ersetzt (die Platzhalter dürfen natürlich nicht im Text vorkommen).
Dann im zweiten Durchlauf, die Platzhalter durch die Links ersetzen.
Wie gesagt: das wäre die einfache Variante - keine schöne :p

Java:
public class RefHTML {

    // Choose a key that does never occure in the text!!
    // Add more characters to make it save ^_^
    private static final String KEY = "{{%d}}";
  
    private static final String LINKS[][] = {
        {"dolor", "http://a.com"},
        {"dolor sit", "http://b.com"},
        {"link me", "http://c.de"},
        {"link", "http://d.de"}
    };
  
    private static final Comparator<String[]> SORT = (String[] o1, String[] o2) -> Integer.compare(o2[0].length(), o1[0].length()); // Unsave for null-objects or empty arrays
  
    public static void main(String[] args) {
        String res = link("Ein unsinniger Text mit Link und Link Me! gedöns ^_^ Dolor dolor sit dolor und so weiter dolor sit...");
        System.out.println(res);
    }
  
    public static String link(String text) {
        Arrays.sort(LINKS, SORT);
        String result = text;
        for (int i=0; i<LINKS.length; i++) {
            result = result.replaceAll("(?i)" + LINKS[i][0], String.format(KEY, i));
        }
        for (int i=0; i<LINKS.length; i++) {
            result = result.replace(String.format(KEY, i), "<a href=\"" + LINKS[i][1] + "\">" + LINKS[i][0] + "</a>");
        }
        return result;
    }
}
Das (?i) ist ein RegEx, damit die Groß-Kleinschreibung am Anfang des Wortes ignoriert wird.
 

jimb0p

Erfahrenes Mitglied
#7
Danke für die Hilfe euch beiden! Habe noch das Maximum mit eingebaut. Funktioniert einwandfrei. Sieht so aus:

Java:
        //Entfernt vorherige Links aus dem Text
        Document doc = Jsoup.parse(result, "UTF-8");
        Elements links = doc.select("a[href]");
        for(int i = 0; i < links.size(); i++) {
            result = result.replace(links.get(i).toString(), String.format(MEMKEY, i));
        }
     
        //Setzt Platzhalter für alle Keywords (groß nach klein)
        for (int i = 0; i < keywordLinkList.size(); i++) {
            BlogLinkEntry tmpEntry = keywordLinkList.get(i);
            for (int j = 0; j < tmpEntry.getKeywords().size(); j++) {
                while (result.contains(tmpEntry.getKeywords().get(j))) {
                    if (tmpEntry.getMaximum() > 0) {
                        result = result.replaceFirst("(?i)" + tmpEntry.getKeywords().get(j), String.format(KEY, i, j));
                        tmpEntry.setMaximum(tmpEntry.getMaximum()-1);
                    }
                    else {
                        break;
                    }
                }
                if(tmpEntry.getMaximum() == 0){
                    break;
                }
            }
        }
     
        //ersetzt Platzhalter durch Keywords
        for (int i = 0; i < keywordLinkList.size(); i++) {
            BlogLinkEntry tmpEntry = keywordLinkList.get(i);
            for (int j = 0; j < tmpEntry.getKeywords().size(); j++) {
                result = result.replace(String.format(KEY, i, j),"<a href=\""+tmpEntry.getUrl()+"\">"+tmpEntry.getKeywords().get(j)+"</a>");
            }
        }
     
        for (int i = 0; i < links.size(); i++) {
            result = result.replace(String.format(MEMKEY, i), links.get(i).toString());
        }
        return result;
Falls jemand Verbesserungsvorschläge hat: immer her damit! Habe noch eingebaut das bereits vorhandene Verlinkungen erst einmal heraus genommen werden, damit es keine Doppelverlinkungen gibt.
 
Zuletzt bearbeitet:

Neue Beiträge