2010-06-23 4 views
6

Sto cercando di estrarre URL SEO friendly da stringhe che possono contenere caratteri speciali, lettere con accenti, caratteri cinesi simili, ecc.
SO sta facendo questo e sta traducendo questo titolo del post inURL compatibili Java e SEO: © reate ╨ un URL http valido da una stringa composta da caratteri speciali

java-and-seo-friendly-urls-reate--a-valid-http-url-from-a-string-composed-by-s 

che sto cercando di fare questo in Java.
Sto utilizzando la soluzione this post con URLEncoder.encode per tradurre simboli cinesi e altri in caratteri URL validi.

Avete mai implementato qualcosa di simile? C'è un modo migliore?

+0

Questa domanda ha un modo regex base di farlo in PHP: http://stackoverflow.com/questions/2580581/best-way-to-escape-and-create-a-slug –

risposta

1

Non conosco alcun metodo standard per questo, ho utilizzato una soluzione simile a quella a cui si sta riferendo. Non sono sicuro che il proprio meglio, ecco lo avete:

public class TextUtils { 

private static final Pattern DIACRITICS_AND_FRIENDS = 
     Pattern.compile("[\\p{InCombiningDiacriticalMarks}\\p{IsLm}\\p{IsSk}]+"); 

private static final Transliterator TO_LATIN_TRANSLITERATOR = Transliterator.getInstance("Any-Latin"); 

private static final Pattern EEQUIVALENTS = Pattern.compile("[ǝƏ]+"); 
private static final Pattern IEQUIVALENTS = Pattern.compile("[ı]+"); 
private static final Pattern DEQUIVALENTS = Pattern.compile("[Ððđ]+"); 
private static final Pattern OEQUIVALENTS = Pattern.compile("[Øø]+"); 
private static final Pattern LEQUIVALENTS = Pattern.compile("[Ł]+"); 

//all spaces, non-ascii and punctuation characters except _ and - 
private static final Pattern CRAP = Pattern.compile("[\\p{IsSpace}\\P{IsASCII}\\p{IsP}\\+&&[^_]]"); 
private static final Pattern SEPARATORS = Pattern.compile("[\\p{IsSpace}/`-]"); 

private static final Pattern URLFRIENDLY = Pattern.compile("([a-zA-Z0-9_])*"); 
private static final CharsetEncoder ASCII_ENCODER = Charset.forName("ISO-8859-1").newEncoder(); 

/** 
* Returns true when the input test contains only characters from the ASCII set, false otherwise. 
*/ 
public static boolean isPureAscii(String text) { 
    return ASCII_ENCODER.canEncode(text); 
} 

/** 
* Replaces all characters that normalize into two characters with their base symbol (e.g. ü -> u) 
*/ 
public static String replaceCombiningDiacriticalMarks(String text) { 
    return DIACRITICS_AND_FRIENDS.matcher(Normalizer.normalize(text, Normalizer.Form.NFKD)).replaceAll(""); 
} 

/** 
* Turns the input string into a url friendly variant (containing only alphanumeric characters and '-' and '_'). 
* If the input string cannot be converted an IllegalArgumentException is thrown. 
*/ 
public static String urlFriendlyStrict(String unfriendlyString) throws IllegalArgumentException { 
    String friendlyString = 
      urlFriendly(unfriendlyString); 

    //Assert can be removed to improve performance 
    Assert.isTrue(URLFRIENDLY.matcher(friendlyString).matches(), 
      format("Friendly string [%s] based on [%s] is not friendly enough", friendlyString, unfriendlyString)); 
    return friendlyString; 
} 

/** 
* Turns the input string into a url friendly variant (containing only alphanumeric characters and '-' and '_'). 
* Use {@link #urlFriendlyStrict(String)} to avoid potential bugs in this code. 
*/ 
private static String urlFriendly(String unfriendlyString) { 
    return removeCrappyCharacters(
      replaceEquivalentsOfSymbols(
        replaceCombiningDiacriticalMarks(
          transLiterateSymbols(
            replaceSeparatorsWithUnderscores(
              unfriendlyString.trim()))))).toLowerCase(); 
} 

private static String transLiterateSymbols(String incomprehensibleString) { 
    String latin = TO_LATIN_TRANSLITERATOR.transform(incomprehensibleString); 
    return latin; 
} 

private static String replaceEquivalentsOfSymbols(String unfriendlyString) { 
    return 
      LEQUIVALENTS.matcher(
        OEQUIVALENTS.matcher(
          DEQUIVALENTS.matcher(
            IEQUIVALENTS.matcher(
              EEQUIVALENTS.matcher(unfriendlyString).replaceAll("e")) 
              .replaceAll("i")) 
            .replaceAll("d")) 
          .replaceAll("o")) 
        .replaceAll("l"); 
} 

private static String removeCrappyCharacters(String unfriendlyString) { 
    return CRAP.matcher(unfriendlyString).replaceAll(""); 
} 

private static String replaceSeparatorsWithUnderscores(String unfriendlyString) { 
    return SEPARATORS.matcher(unfriendlyString).replaceAll("_"); 
} 

}

0

direi URLEncoder.encode è la strada da percorrere. Tutti i caratteri non URL sono mappati e sicuramente non si desidera reinventare la ruota (ancora e ancora e ancora).

+0

Sì, ma i caratteri di codifica sono l'ultimo passo (dopo aver eliminato gli accenti di stringa, ecc.) per ottenere un URL valido. I caratteri codificati non sono SEO friendly ... non funzionano bene nelle ricerche. – mickthompson

2

Questo potrebbe essere un approccio eccessivamente complicato al problema, ma è sufficiente utilizzare espressioni regolari per rimuovere tutti i caratteri non standard. Quindi, dopo aver convertito la stringa in minuscolo, puoi sostituire tutti i caratteri alfabetici non in minuscolo con un carattere vuoto e quindi sostituire tutti gli spazi con il carattere '-'.

private static String encodeForUrl(String input) { 
    return input.toLowerCase().replaceAll("[^a-z\\s]", "").replaceAll("\\s", "-"); 
}