2010-06-23 31 views
6

Tôi đang cố gắng trích xuất URL thân thiện với SEO từ chuỗi có thể chứa các ký tự đặc biệt, chữ cái có dấu, ký tự Trung Quốc, v.v.
SO được làm điều này và nó dịch tiêu đề bài đăng này trongURL thân thiện với Java và SEO: © reate ╨ URL http hợp lệ từ chuỗi được tạo bởi các ký tự đặc biệt

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

tôi đang cố gắng để làm điều này trong Java.
Tôi đang sử dụng giải pháp this post với URLEncoder.encode để dịch các ký tự Trung Quốc và các ký tự khác thành các ký tự URL hợp lệ.

Bạn đã bao giờ triển khai một cái gì đó như thế này chưa? Có cách nào tốt hơn?

+0

Câu hỏi này có một cách regex dựa để làm điều đó trong PHP: http://stackoverflow.com/questions/2580581/best-way-to-escape-and-create-a-slug –

Trả lời

1

Tôi không biết cách nào tiêu chuẩn cho điều này, tôi đã sử dụng giải pháp similair như những gì bạn đang đề cập đến. Không chắc chắn của một người tốt hơn, vì vậy ở đây bạn có nó:

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

tôi sẽ nói URLEncoder.encode là con đường để đi. Tất cả các ký tự không phải URL đều được ánh xạ và bạn chắc chắn không muốn phát minh lại bánh xe (lặp đi lặp lại và lặp lại).

+0

Có, nhưng các ký tự mã hóa là bước cuối cùng (sau khi làm sạch các dấu móc String vv) để có được một URL hợp lệ. Các ký tự được mã hóa không thân thiện với SEO ... không hoạt động tốt trong các tìm kiếm. – mickthompson

2

Đây có thể là một cách tiếp cận quá mô phỏng vấn đề, nhưng bạn chỉ có thể sử dụng cụm từ thông dụng để xóa tất cả các ký tự không chuẩn. Vì vậy, sau khi chuyển đổi chuỗi thành chữ thường, bạn có thể thay thế tất cả các ký tự chữ thường không phải chữ thường bằng ký tự trống và sau đó thay thế tất cả dấu cách bằng ký tự '-'.

private static String encodeForUrl(String input) { 
    return input.toLowerCase().replaceAll("[^a-z\\s]", "").replaceAll("\\s", "-"); 
} 
Các vấn đề liên quan