Como converter um título em uma lesma de URL no jQuery?

163

Estou trabalhando em um aplicativo no CodeIgniter e estou tentando criar um campo em um formulário para gerar dinamicamente a lesma de URL. O que eu gostaria de fazer é remover a pontuação, convertê-la em minúscula e substituir os espaços por hífens. Assim, por exemplo, o Rib Shack de Shane se tornaria shanes-rib-shack.

Aqui está o que eu tenho até agora. A parte em minúscula foi fácil, mas a substituição não parece estar funcionando e não faço ideia de remover a pontuação:

$("#Restaurant_Name").keyup(function(){
    var Text = $(this).val();
    Text = Text.toLowerCase();
    Text = Text.replace('/\s/g','-');
    $("#Restaurant_Slug").val(Text);    
});
GSto
fonte
2
Não jQuery, mas olhar para as bibliotecas dos speakingurl 'ou 'nó-lesma'
Kevin Wheeler
... ou slugify
x-yuri

Respostas:

379

Não faço ideia de onde veio o termo 'lesma', mas aqui vamos nós:

function convertToSlug(Text)
{
    return Text
        .toLowerCase()
        .replace(/ /g,'-')
        .replace(/[^\w-]+/g,'')
        ;
}

A primeira substituição altera os espaços para hífens; a segunda substituição remove qualquer coisa que não seja alfanumérica, sublinhada ou hífen.

Se você não quer coisas "como - isto" se transformando em "como --- isto", então você pode usar este:

function convertToSlug(Text)
{
    return Text
        .toLowerCase()
        .replace(/[^\w ]+/g,'')
        .replace(/ +/g,'-')
        ;
}

Isso removerá hífens (mas não espaços) na primeira substituição e, na segunda substituição, condensará espaços consecutivos em um único hífen.

Então "like - this" sai como "like-this".

Peter Boughton
fonte
1
não se esqueça de adicionar "/" também se você precisar de vários diretórios separados
Val
6
o termo "lesma" veio de wordpress
Brynner Ferreira
18
Para evitar vários hífens seqüenciais, usei em text.toLowerCase().replace(/ /g,'-').replace(/[-]+/g, '-').replace(/[^\w-]+/g,'');vez da opção 2. A opção 2 mudará "th - is" para "this".
Ryan Allen
Como também permito pontos no URL?
Identifique-se com o código
Para evitar "_" na lesma, substitua .replace (/ + / g, '-') para .replace (/ + | _ / g, '-').
Odin Thunder
112
var slug = function(str) {
  str = str.replace(/^\s+|\s+$/g, ''); // trim
  str = str.toLowerCase();

  // remove accents, swap ñ for n, etc
  var from = "ãàáäâẽèéëêìíïîõòóöôùúüûñç·/_,:;";
  var to   = "aaaaaeeeeeiiiiooooouuuunc------";
  for (var i=0, l=from.length ; i<l ; i++) {
    str = str.replace(new RegExp(from.charAt(i), 'g'), to.charAt(i));
  }

  str = str.replace(/[^a-z0-9 -]/g, '') // remove invalid chars
    .replace(/\s+/g, '-') // collapse whitespace and replace by -
    .replace(/-+/g, '-'); // collapse dashes

  return str;
};

e tentar

slug($('#field').val())

original por: http://dense13.com/blog/2009/05/03/converting-string-to-slug-javascript/


EDIT: estendido para mais caracteres específicos do idioma:

var from = "ÁÄÂÀÃÅČÇĆĎÉĚËÈÊẼĔȆĞÍÌÎÏİŇÑÓÖÒÔÕØŘŔŠŞŤÚŮÜÙÛÝŸŽáäâàãåčçćďéěëèêẽĕȇğíìîïıňñóöòôõøðřŕšşťúůüùûýÿžþÞĐđßÆa·/_,:;";
var to   = "AAAAAACCCDEEEEEEEEGIIIIINNOOOOOORRSSTUUUUUYYZaaaaaacccdeeeeeeeegiiiiinnooooooorrsstuuuuuyyzbBDdBAa------";
Taranttini
fonte
6
Mas não corretamente. Nos textos em alemão, üdeve ser substituído por ue, etc.
feklee 28/10/12
5
@feklee: "Não corretamente" é verdade para o alemão (e possivelmente para outros idiomas), mas em outros idiomas é ótimo. Para um site em inglês, eu gostaria que "Márföldi" (sobrenome de origem húngara) fosse convertido em "marfoldi", e não "marfoeldi", como os alemães.
michalstanko
1
Para garantir a compatibilidade entre plataformas, convém fazer a subscrição de = "\ u00E3 \ u00E0 \ u00E1 \ u00E4 \ u00E2 \ u1EBD \ u00E8 \ u00E9 \ u00EB \ u00EA \ u00EC \ u00ED \ u00EF \ u00EE \ u00F5 \ u00F2 \ u00F6 \ u00F4 \ u00F9 \ u00FA \ u00FC \ u00FB \ u00F1 \ u00E7 \ u00B7 / _,:; ";
Mike Godin
1
Ótima solução! Faltando o escandinavo åembora.
Fredric
1
Você pode adicionar İĞŞığşà fromvariável e convertê-la em IGSigspara suportar caracteres turcos.
CemilF
19

Antes de tudo, expressões regulares não devem conter aspas, portanto '/ \ s / g' deve ser / \ s / g

Para substituir todos os caracteres não alfanuméricos por traços, isso deve funcionar (usando seu código de exemplo):

$("#Restaurant_Name").keyup(function(){
        var Text = $(this).val();
        Text = Text.toLowerCase();
        Text = Text.replace(/[^a-zA-Z0-9]+/g,'-');
        $("#Restaurant_Slug").val(Text);        
});

Isso deve fazer o truque ...

Philippe Leybaert
fonte
8

Encontrei uma solução boa e completa para o inglês

function slugify(string) {
  return string
    .toString()
    .trim()
    .toLowerCase()
    .replace(/\s+/g, "-")
    .replace(/[^\w\-]+/g, "")
    .replace(/\-\-+/g, "-")
    .replace(/^-+/, "")
    .replace(/-+$/, "");
}

Alguns exemplos disso em uso:

slugify(12345);
// "12345"

slugify("  string with leading   and   trailing whitespace    ");
// "string-with-leading-and-trailing-whitespace"

slugify("mIxEd CaSe TiTlE");
// "mixed-case-title"

slugify("string with - existing hyphens -- ");
// "string-with-existing-hyphens"

slugify("string with Special™ characters");
// "string-with-special-characters"

Agradecimentos a Andrew Stewart

zahid9i
fonte
8

Espero que isso possa salvar o dia de alguém ...

/* Encode string to slug */
function convertToSlug( str ) {
	
  //replace all special characters | symbols with a space
  str = str.replace(/[`~!@#$%^&*()_\-+=\[\]{};:'"\\|\/,.<>?\s]/g, ' ').toLowerCase();
	
  // trim spaces at start and end of string
  str = str.replace(/^\s+|\s+$/gm,'');
	
  // replace space with dash/hyphen
  str = str.replace(/\s+/g, '-');	
  document.getElementById("slug-text").innerHTML= str;
  //return str;
}
<input type="text" onload="convertToSlug(this.value)" onkeyup="convertToSlug(this.value)" value="Try it Yourself"/>
<p id="slug-text"></p>

bmatovu
fonte
7

Tudo o que você precisava era de um plus :)

$("#Restaurant_Name").keyup(function(){
        var Text = $(this).val();
        Text = Text.toLowerCase();
        var regExp = /\s+/g;
        Text = Text.replace(regExp,'-');
        $("#Restaurant_Slug").val(Text);        
});
karim79
fonte
6

Dê uma olhada nesta função slug para limpar URLs, desenvolvida por Sean Murphy em https://gist.github.com/sgmurphy/3095196

/**
 * Create a web friendly URL slug from a string.
 *
 * Requires XRegExp (http://xregexp.com) with unicode add-ons for UTF-8 support.
 *
 * Although supported, transliteration is discouraged because
 *     1) most web browsers support UTF-8 characters in URLs
 *     2) transliteration causes a loss of information
 *
 * @author Sean Murphy <[email protected]>
 * @copyright Copyright 2012 Sean Murphy. All rights reserved.
 * @license http://creativecommons.org/publicdomain/zero/1.0/
 *
 * @param string s
 * @param object opt
 * @return string
 */
function url_slug(s, opt) {
    s = String(s);
    opt = Object(opt);

    var defaults = {
        'delimiter': '-',
        'limit': undefined,
        'lowercase': true,
        'replacements': {},
        'transliterate': (typeof(XRegExp) === 'undefined') ? true : false
    };

    // Merge options
    for (var k in defaults) {
        if (!opt.hasOwnProperty(k)) {
            opt[k] = defaults[k];
        }
    }

    var char_map = {
        // Latin
        'À': 'A', 'Á': 'A', 'Â': 'A', 'Ã': 'A', 'Ä': 'A', 'Å': 'A', 'Æ': 'AE', 'Ç': 'C', 
        'È': 'E', 'É': 'E', 'Ê': 'E', 'Ë': 'E', 'Ì': 'I', 'Í': 'I', 'Î': 'I', 'Ï': 'I', 
        'Ð': 'D', 'Ñ': 'N', 'Ò': 'O', 'Ó': 'O', 'Ô': 'O', 'Õ': 'O', 'Ö': 'O', 'Ő': 'O', 
        'Ø': 'O', 'Ù': 'U', 'Ú': 'U', 'Û': 'U', 'Ü': 'U', 'Ű': 'U', 'Ý': 'Y', 'Þ': 'TH', 
        'ß': 'ss', 
        'à': 'a', 'á': 'a', 'â': 'a', 'ã': 'a', 'ä': 'a', 'å': 'a', 'æ': 'ae', 'ç': 'c', 
        'è': 'e', 'é': 'e', 'ê': 'e', 'ë': 'e', 'ì': 'i', 'í': 'i', 'î': 'i', 'ï': 'i', 
        'ð': 'd', 'ñ': 'n', 'ò': 'o', 'ó': 'o', 'ô': 'o', 'õ': 'o', 'ö': 'o', 'ő': 'o', 
        'ø': 'o', 'ù': 'u', 'ú': 'u', 'û': 'u', 'ü': 'u', 'ű': 'u', 'ý': 'y', 'þ': 'th', 
        'ÿ': 'y',

        // Latin symbols
        '©': '(c)',

        // Greek
        'Α': 'A', 'Β': 'B', 'Γ': 'G', 'Δ': 'D', 'Ε': 'E', 'Ζ': 'Z', 'Η': 'H', 'Θ': '8',
        'Ι': 'I', 'Κ': 'K', 'Λ': 'L', 'Μ': 'M', 'Ν': 'N', 'Ξ': '3', 'Ο': 'O', 'Π': 'P',
        'Ρ': 'R', 'Σ': 'S', 'Τ': 'T', 'Υ': 'Y', 'Φ': 'F', 'Χ': 'X', 'Ψ': 'PS', 'Ω': 'W',
        'Ά': 'A', 'Έ': 'E', 'Ί': 'I', 'Ό': 'O', 'Ύ': 'Y', 'Ή': 'H', 'Ώ': 'W', 'Ϊ': 'I',
        'Ϋ': 'Y',
        'α': 'a', 'β': 'b', 'γ': 'g', 'δ': 'd', 'ε': 'e', 'ζ': 'z', 'η': 'h', 'θ': '8',
        'ι': 'i', 'κ': 'k', 'λ': 'l', 'μ': 'm', 'ν': 'n', 'ξ': '3', 'ο': 'o', 'π': 'p',
        'ρ': 'r', 'σ': 's', 'τ': 't', 'υ': 'y', 'φ': 'f', 'χ': 'x', 'ψ': 'ps', 'ω': 'w',
        'ά': 'a', 'έ': 'e', 'ί': 'i', 'ό': 'o', 'ύ': 'y', 'ή': 'h', 'ώ': 'w', 'ς': 's',
        'ϊ': 'i', 'ΰ': 'y', 'ϋ': 'y', 'ΐ': 'i',

        // Turkish
        'Ş': 'S', 'İ': 'I', 'Ç': 'C', 'Ü': 'U', 'Ö': 'O', 'Ğ': 'G',
        'ş': 's', 'ı': 'i', 'ç': 'c', 'ü': 'u', 'ö': 'o', 'ğ': 'g', 

        // Russian
        'А': 'A', 'Б': 'B', 'В': 'V', 'Г': 'G', 'Д': 'D', 'Е': 'E', 'Ё': 'Yo', 'Ж': 'Zh',
        'З': 'Z', 'И': 'I', 'Й': 'J', 'К': 'K', 'Л': 'L', 'М': 'M', 'Н': 'N', 'О': 'O',
        'П': 'P', 'Р': 'R', 'С': 'S', 'Т': 'T', 'У': 'U', 'Ф': 'F', 'Х': 'H', 'Ц': 'C',
        'Ч': 'Ch', 'Ш': 'Sh', 'Щ': 'Sh', 'Ъ': '', 'Ы': 'Y', 'Ь': '', 'Э': 'E', 'Ю': 'Yu',
        'Я': 'Ya',
        'а': 'a', 'б': 'b', 'в': 'v', 'г': 'g', 'д': 'd', 'е': 'e', 'ё': 'yo', 'ж': 'zh',
        'з': 'z', 'и': 'i', 'й': 'j', 'к': 'k', 'л': 'l', 'м': 'm', 'н': 'n', 'о': 'o',
        'п': 'p', 'р': 'r', 'с': 's', 'т': 't', 'у': 'u', 'ф': 'f', 'х': 'h', 'ц': 'c',
        'ч': 'ch', 'ш': 'sh', 'щ': 'sh', 'ъ': '', 'ы': 'y', 'ь': '', 'э': 'e', 'ю': 'yu',
        'я': 'ya',

        // Ukrainian
        'Є': 'Ye', 'І': 'I', 'Ї': 'Yi', 'Ґ': 'G',
        'є': 'ye', 'і': 'i', 'ї': 'yi', 'ґ': 'g',

        // Czech
        'Č': 'C', 'Ď': 'D', 'Ě': 'E', 'Ň': 'N', 'Ř': 'R', 'Š': 'S', 'Ť': 'T', 'Ů': 'U', 
        'Ž': 'Z', 
        'č': 'c', 'ď': 'd', 'ě': 'e', 'ň': 'n', 'ř': 'r', 'š': 's', 'ť': 't', 'ů': 'u',
        'ž': 'z', 

        // Polish
        'Ą': 'A', 'Ć': 'C', 'Ę': 'e', 'Ł': 'L', 'Ń': 'N', 'Ó': 'o', 'Ś': 'S', 'Ź': 'Z', 
        'Ż': 'Z', 
        'ą': 'a', 'ć': 'c', 'ę': 'e', 'ł': 'l', 'ń': 'n', 'ó': 'o', 'ś': 's', 'ź': 'z',
        'ż': 'z',

        // Latvian
        'Ā': 'A', 'Č': 'C', 'Ē': 'E', 'Ģ': 'G', 'Ī': 'i', 'Ķ': 'k', 'Ļ': 'L', 'Ņ': 'N', 
        'Š': 'S', 'Ū': 'u', 'Ž': 'Z', 
        'ā': 'a', 'č': 'c', 'ē': 'e', 'ģ': 'g', 'ī': 'i', 'ķ': 'k', 'ļ': 'l', 'ņ': 'n',
        'š': 's', 'ū': 'u', 'ž': 'z'
    };

    // Make custom replacements
    for (var k in opt.replacements) {
        s = s.replace(RegExp(k, 'g'), opt.replacements[k]);
    }

    // Transliterate characters to ASCII
    if (opt.transliterate) {
        for (var k in char_map) {
            s = s.replace(RegExp(k, 'g'), char_map[k]);
        }
    }

    // Replace non-alphanumeric characters with our delimiter
    var alnum = (typeof(XRegExp) === 'undefined') ? RegExp('[^a-z0-9]+', 'ig') : XRegExp('[^\\p{L}\\p{N}]+', 'ig');
    s = s.replace(alnum, opt.delimiter);

    // Remove duplicate delimiters
    s = s.replace(RegExp('[' + opt.delimiter + ']{2,}', 'g'), opt.delimiter);

    // Truncate slug to max. characters
    s = s.substring(0, opt.limit);

    // Remove delimiter from ends
    s = s.replace(RegExp('(^' + opt.delimiter + '|' + opt.delimiter + '$)', 'g'), '');

    return opt.lowercase ? s.toLowerCase() : s;
}
Máx.
fonte
1
Nos commets, alguém disse "Isso não funcionará com o uso estrito nos navegadores IE11 por causa de duplicatas no objeto char_map".
BBaysinger 31/03
3

Eu crio um plugin para implementar na maioria dos idiomas: http://leocaseiro.com.br/jquery-plugin-string-to-slug/

Uso padrão:

$(document).ready( function() {
    $("#string").stringToSlug();
});

É muito fácil tem o plugin jQuery stringToSlug

Leo Caseiro
fonte
3
function slugify(text){
  return text.toString().toLowerCase()
    .replace(/\s+/g, '-')           // Replace spaces with -
    .replace(/[^\u0100-\uFFFF\w\-]/g,'-') // Remove all non-word chars ( fix for UTF-8 chars )
    .replace(/\-\-+/g, '-')         // Replace multiple - with single -
    .replace(/^-+/, '')             // Trim - from start of text
    .replace(/-+$/, '');            // Trim - from end of text
}

*baseado em https://gist.github.com/mathewbyrne/1280286

agora você pode transformar esta string:

Barack_Obama       Барак_Обама ~!@#$%^&*()+/-+?><:";'{}[]\|`

para dentro:

barack_obama-барак_обама

aplicando ao seu código:

$("#Restaurant_Name").keyup(function(){
    var Text = $(this).val();
    Text = slugify(Text);
    $("#Restaurant_Slug").val(Text);
});
Alexander Ivashchenko
fonte
Não sei por que isso não está selecionado como a resposta correta. Muitas das respostas não contam com a remoção de # ou? da lesma - os URLs são danificados dessa maneira. Mesmo as bibliotecas de reação mais usadas não possuem esse recurso implementado. Esta resposta é muito simples, mas universal.
Vladimir Marton
3

Combinar uma variedade de elementos das respostas aqui com normalizar fornece uma boa cobertura. Mantenha a ordem das operações para limpar incrementalmente o URL.

function clean_url(s) {
    return s.toString().normalize('NFD').replace(/[\u0300-\u036f]/g, "") //remove diacritics
            .toLowerCase()
            .replace(/\s+/g, '-') //spaces to dashes
            .replace(/&/g, '-and-') //ampersand to and
            .replace(/[^\w\-]+/g, '') //remove non-words
            .replace(/\-\-+/g, '-') //collapse multiple dashes
            .replace(/^-+/, '') //trim starting dash
            .replace(/-+$/, ''); //trim ending dash
}

normlize('NFD')quebra os caracteres acentuados em seus componentes, que são letras básicas e sinais diacríticos (a parte de acentuação). replace(/[\u0300-\u036f]/g, "")limpa todos os diacríticos, deixando as letras básicas por si só. O restante é explicado com comentários embutidos.

OXiGEN
fonte
1
Te agradece. Isso é simples e funciona bem com meus casos de teste. Até o caracter vietnamita `` const testCases = [{input: 'é uma boa lesma' ', espera:' is-it-a-good-lesma '}, {input:' ----- is --- --it ----- a ----- bom ----- lesma ----- ', expect:' is-it-a-good-lesma '}, {input:' CÔNG cha như núi Thái Sơn ', espera:' cong-cha-nhu-nui-tailandês-filho '}, {input:' -Haha - Nhất-Nguyễn ', espera:' haha-nhat-nguyen '}] ``
Phat Tran Ky
1

Você pode usar sua própria função para isso.

tente: http://jsfiddle.net/xstLr7aj/

function string_to_slug(str) {
  str = str.replace(/^\s+|\s+$/g, ''); // trim
  str = str.toLowerCase();

  // remove accents, swap ñ for n, etc
  var from = "àáäâèéëêìíïîòóöôùúüûñç·/_,:;";
  var to   = "aaaaeeeeiiiioooouuuunc------";
  for (var i=0, l=from.length ; i<l ; i++) {
    str = str.replace(new RegExp(from.charAt(i), 'g'), to.charAt(i));
  }

  str = str.replace(/[^a-z0-9 -]/g, '') // remove invalid chars
    .replace(/\s+/g, '-') // collapse whitespace and replace by -
    .replace(/-+/g, '-'); // collapse dashes

  return str;
}
$(document).ready(function() {
    $('#test').submit(function(){
        var val = string_to_slug($('#t').val());
        alert(val);
        return false;
    });
});
MGE
fonte
Qual é a diferença nesta solução da resposta altamente votada acima?
Nilsi
código atualizado aqui, para remover o último caractere se for "-" jsfiddle.net/xstLr7aj/36
MGE 14/11
1

A resposta aceita não atendeu às minhas necessidades (permite sublinhados, não processa hífens no começo e no fim etc.) e as outras respostas tiveram outros problemas que não se adequavam ao meu caso de uso, então aqui está a função slugify Eu vim com:

function slugify(string) {
    return string.trim() // Remove surrounding whitespace.
    .toLowerCase() // Lowercase.
    .replace(/[^a-z0-9]+/g,'-') // Find everything that is not a lowercase letter or number, one or more times, globally, and replace it with a dash.
    .replace(/^-+/, '') // Remove all dashes from the beginning of the string.
    .replace(/-+$/, ''); // Remove all dashes from the end of the string.
}

Isso transformará 'foo !!! BAR _-_-_ baz-' (observe o espaço no começo) em foo-bar-baz.

Justin Michael
fonte
1

Você pode dar uma olhada no plug - in speakingURL e então você pode:

    $("#Restaurant_Name").on("keyup", function () {
        var slug = getSlug($("#Restaurant_Name").val());
        $("#Restaurant_Slug").val(slug);
    });
Kornel
fonte
1

Mais um. Curto e mantém caracteres especiais:

imaginação é mato => imaginação-e-mato

function slugify (text) {
  const a = 'àáäâãèéëêìíïîòóöôùúüûñçßÿœæŕśńṕẃǵǹḿǘẍźḧ·/_,:;'
  const b = 'aaaaaeeeeiiiioooouuuuncsyoarsnpwgnmuxzh------'
  const p = new RegExp(a.split('').join('|'), 'g')

  return text.toString().toLowerCase()
    .replace(/\s+/g, '-')           // Replace spaces with -
    .replace(p, c =>
        b.charAt(a.indexOf(c)))     // Replace special chars
    .replace(/&/g, '-and-')         // Replace & with 'and'
    .replace(/[^\w\-]+/g, '')       // Remove all non-word chars
    .replace(/\-\-+/g, '-')         // Replace multiple - with single -
    .replace(/^-+/, '')             // Trim - from start of text
    .replace(/-+$/, '')             // Trim - from end of text
}
Lucas Bustamante
fonte
1

Método de geração de lesmas mais poderoso em JavaScript puro. É basicamente suporte à transliteração para todos os caracteres cirílicos e muitos trema (alemão, dinamarquês, França, turco, ucraniano e etc.), mas pode ser facilmente estendido.

function makeSlug(str)
{
  var from="а б в г д е ё ж з и й к л м н о п р с т у ф х ц ч ш щ ъ ы ь э ю я ā ą ä á à â å č ć ē ę ě é è ê æ ģ ğ ö ó ø ǿ ô ő ḿ ʼn ń ṕ ŕ ş ü ß ř ł đ þ ĥ ḧ ī ï í î ĵ ķ ł ņ ń ň ř š ś ť ů ú û ứ ù ü ű ū ý ÿ ž ź ż ç є ґ".split(' ');
  var to=  "a b v g d e e zh z i y k l m n o p r s t u f h ts ch sh shch # y # e yu ya a a ae a a a a c c e e e e e e e g g oe o o o o o m n n p r s ue ss r l d th h h i i i i j k l n n n r s s t u u u u u u u u y y z z z c ye g".split(' ');
	
  str = str.toLowerCase();
  
  // remove simple HTML tags
  str = str.replace(/(<[a-z0-9\-]{1,15}[\s]*>)/gi, '');
  str = str.replace(/(<\/[a-z0-9\-]{1,15}[\s]*>)/gi, '');
  str = str.replace(/(<[a-z0-9\-]{1,15}[\s]*\/>)/gi, '');
  
  str = str.replace(/^\s+|\s+$/gm,''); // trim spaces
  
  for(i=0; i<from.length; ++i)
    str = str.split(from[i]).join(to[i]);
  
  // Replace different kind of spaces with dashes
  var spaces = [/(&nbsp;|&#160;|&#32;)/gi, /(&mdash;|&ndash;|&#8209;)/gi,
     /[(_|=|\\|\,|\.|!)]+/gi, /\s/gi];

  for(i=0; i<from.length; ++i)
  	str = str.replace(spaces[i], '-');
  str = str.replace(/-{2,}/g, "-");

  // remove special chars like &amp;
  str = str.replace(/&[a-z]{2,7};/gi, '');
  str = str.replace(/&#[0-9]{1,6};/gi, '');
  str = str.replace(/&#x[0-9a-f]{1,6};/gi, '');
  
  str = str.replace(/[^a-z0-9\-]+/gmi, ""); // remove all other stuff
  str = str.replace(/^\-+|\-+$/gm,''); // trim edges
  
  return str;
};


document.getElementsByTagName('pre')[0].innerHTML = makeSlug(" <br/> &#x202A;Про&amp;вер<strong>ка_тран</strong>с…литеърьации\rюга\nи&ndash;южного&nbsp;округа\t \nс\tёжикам&#180;и&nbsp;со\\всеми&ndash;друзьями\tтоже.Danke schön!ich heiße=КáÞÿá-Skånske,København çağatay rí gé tőr zöldülésetekről - . ");
<div>
  <pre>Hello world!</pre>
</div>

anakod
fonte
1

Para pessoas que já usam lodash

A maioria desses exemplos é realmente boa e cobre muitos casos. Mas se você 'sabe' que só tem texto em inglês, aqui está minha versão super fácil de ler :)

_.words(_.toLower(text)).join('-')

Frexuz
fonte
1

Bem, depois de ler as respostas, eu vim com essa.

    const generateSlug = (text) => text.toLowerCase().trim().replace(/[^\w- ]+/g, '').replace(/ /g, '-').replace(/[-]+/g, '-');
Siraj Alam
fonte
1

Nota: se você não se importa com um argumento contra a resposta aceita e está apenas procurando uma resposta, pule a próxima seção, você encontrará minha resposta proposta no final

a resposta aceita tem alguns problemas (na minha opinião):

1) quanto ao primeiro trecho de função:

sem consideração por vários espaços em branco consecutivos

entrada: is it a good slug

recebido: ---is---it---a---good---slug---

esperado: is-it-a-good-slug

sem consideração por múltiplos traços consecutivos

entrada: -----is-----it-----a-----good-----slug-----

recebido: -----is-----it-----a-----good-----slug-----

esperado: is-it-a-good-slug

observe que esta implementação não trata de traços externos (ou espaços em branco), sejam eles múltiplos consecutivos ou caracteres singulares que (tanto quanto eu entendo slugs e seu uso) não são válidos

2) quanto ao segundo trecho de função:

ele cuida dos vários espaços em branco consecutivos convertendo-os em simples, -mas isso não é suficiente, pois os espaços em branco externos (no início e no final da string) são tratados da mesma maneira is it a good slug, retornando-is-it-a-good-slug-

ele também remove traços completamente a partir da entrada que converte algo como --is--it--a--good--slug--'aisitagoodslug , o trecho no comentário por @ ryan-allen cuida de que, deixando os traços exteriores emitir embora sem solução

agora eu sei que não há definição padrão para slugs, e a resposta aceita pode fazer o trabalho (que o usuário que postou a pergunta estava procurando), mas esta é a pergunta SO mais popular sobre slugs no JS, então esses problemas tinha que ser apontado, também (a respeito de fazer o trabalho! ) imagine digitar essa abominação de um URL ( www.blog.com/posts/-----how-----to-----slugify-----a-----string-----) ou até mesmo ser redirecionado para ele em vez de algo como ( www.blog.com/posts/how-to-slugify-a-string), eu sei que esse é um caso extremo, mas é isso que testes são para.

uma solução melhor , na minha opinião, seria a seguinte:

const slugify = str =>
  str
  .trim()                      // remove whitespaces at the start and end of string
  .toLowerCase()              
  .replace(/^-+/g, "")         // remove one or more dash at the start of the string
  .replace(/[^\w-]+/g, "-")    // convert any on-alphanumeric character to a dash
  .replace(/-+/g, "-")         // convert consecutive dashes to singuar one
  .replace(/-+$/g, "");        // remove one or more dash at the end of the string

agora provavelmente existe um ninja RegExp por aí que pode converter isso em uma expressão de uma linha, não sou especialista em RegExp e não estou dizendo que esta é a melhor ou mais compacta solução ou aquela com o melhor desempenho mas espero que possa fazer o trabalho.

Waddah
fonte
Isso tem uma falha na qual a conversão de caracteres não alfanuméricos em traços possivelmente restaurará um traço no início da linha. Mas, por favor, não faça dele um forro. Este é fácil de entender!
Timo
1
$("#Restaurant_Name").keyup(function(){
        var Text = $(this).val();
        Text = Text.toLowerCase();
        Text = Text.replace(/[^a-zA-Z0-9]+/g,'-');
        $("#Restaurant_Slug").val(Text);        
});

Este código está funcionando

Deepak K. sah
fonte
Obrigado! Isso é mais fácil de usar.
Jane Doe
0
//
//  jQuery Slug Plugin by Perry Trinier ([email protected])
//  MIT License: http://www.opensource.org/licenses/mit-license.php

jQuery.fn.slug = function(options) {
var settings = {
    slug: 'slug', // Class used for slug destination input and span. The span is created on $(document).ready() 
    hide: true   // Boolean - By default the slug input field is hidden, set to false to show the input field and hide the span. 
};

if(options) {
    jQuery.extend(settings, options);
}

$this = $(this);

$(document).ready( function() {
    if (settings.hide) {
        $('input.' + settings.slug).after("<span class="+settings.slug+"></span>");
        $('input.' + settings.slug).hide();
    }
});

makeSlug = function() {
        var slug = jQuery.trim($this.val()) // Trimming recommended by Brooke Dukes - http://www.thewebsitetailor.com/2008/04/jquery-slug-plugin/comment-page-1/#comment-23
                    .replace(/\s+/g,'-').replace(/[^a-zA-Z0-9\-]/g,'').toLowerCase() // See http://www.djangosnippets.org/snippets/1488/ 
                    .replace(/\-{2,}/g,'-'); // If we end up with any 'multiple hyphens', replace with just one. Temporary bugfix for input 'this & that'=>'this--that'
        $('input.' + settings.slug).val(slug);
        $('span.' + settings.slug).text(slug);

    }

$(this).keyup(makeSlug);

return $this;
    };

Isso me ajudou com o mesmo problema!

Marko Ranković
fonte
0
function slugify(content) {
   return content.toLowerCase().replace(/ /g,'-').replace(/[^\w-]+/g,'');
}
// slugify('Hello World');
// this will return 'hello-world';

isso funciona para mim bem.

Encontrado no CodeSnipper

Al Quarashi
fonte
-5
private string ToSeoFriendly(string title, int maxLength) {
    var match = Regex.Match(title.ToLower(), "[\\w]+");
    StringBuilder result = new StringBuilder("");
    bool maxLengthHit = false;
    while (match.Success && !maxLengthHit) {
        if (result.Length + match.Value.Length <= maxLength) {
            result.Append(match.Value + "-");
        } else {
            maxLengthHit = true;
            // Handle a situation where there is only one word and it is greater than the max length.
            if (result.Length == 0) result.Append(match.Value.Substring(0, maxLength));
        }
        match = match.NextMatch();
    }
    // Remove trailing '-'
    if (result[result.Length - 1] == '-') result.Remove(result.Length - 1, 1);
    return result.ToString();
}

fonte