Java и SEO дружественные URL: ©reate ╨ допустимый http URL от строки, составленной специальными символами

Я пытаюсь извлечь SEO дружественные URL из строк, которые могут содержать специальные символы, букву с диакритическими знаками, китайским языком как символы, и т.д.
ТАК делает это, и это переводит этот заголовок сообщения в

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

Я пытаюсь сделать это в Java.
Я использую это решение для сообщения с URLEncoder.encode для перевода китайского языка и других символов в допустимые символы URL.

Вы когда-либо реализовывали что-то вроде этого? Существует ли лучший путь?

6
задан Community 23 May 2017 в 12:30
поделиться

3 ответа

Это может быть чрезмерно упрощенный подход к проблеме, но вы можете просто использовать регулярные выражения для удаления всех нестандартных символов. Поэтому после преобразования строки в нижний регистр вы можете заменить все буквенные символы, отличные от нижнего регистра, пустым символом, а затем заменить все пробелы символом '-'.

private static String encodeForUrl(String input) {
  return input.toLowerCase().replaceAll("[^a-z\\s]", "").replaceAll("\\s", "-");
}
2
ответ дан 17 December 2019 в 18:09
поделиться

Я не знаю стандартного способа для этого, я использовал аналогичное решение, на которое вы ссылаетесь. Не уверен, какое из них лучше, так что вот оно:

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("_");
}

}

1
ответ дан 17 December 2019 в 18:09
поделиться

Я бы сказал, что URLEncoder.encode - это то, что вам нужно. Сопоставлены все символы, не относящиеся к URL, и вы, конечно же, не хотите изобретать велосипед (снова и снова и снова).

0
ответ дан 17 December 2019 в 18:09
поделиться
Другие вопросы по тегам:

Похожие вопросы: