如何在jQuery中将标题转换为URL slug?

GSt*_*Sto 154 javascript regex jquery

我正在使用CodeIgniter中的应用程序,我正在尝试在表单上创建一个字段来动态生成URL slug.我想要做的是删除标点符号,将其转换为小写,并用连字符替换空格.因此,例如,Shane的Rib Shack将成为shanes-rib-shack.

这是我到目前为止所拥有的.小写部分很简单,但替换似乎根本不起作用,我不知道删除标点符号:

$("#Restaurant_Name").keyup(function(){
    var Text = $(this).val();
    Text = Text.toLowerCase();
    Text = Text.replace('/\s/g','-');
    $("#Restaurant_Slug").val(Text);    
});
Run Code Online (Sandbox Code Playgroud)

Pet*_*ton 347

我不知道'slug'这个术语来自哪里,但我们走了:

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

第一次替换会将空格更改为连字符,第二次替换会删除任何不是字母数字,下划线或连字符的内容.

如果你不希望"喜欢 - 这个"的东西变成"喜欢---这个"那么你可以改为使用这个:

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

这将在第一次替换时删除连字符(但不是空格),在第二次替换时,它会将连续的空格压缩成单个连字符.

所以"喜欢 - 这个"就像"喜欢这个".

  • 为了避免多个连续的连字符,我使用了`text.toLowerCase().replace(/ /g,' - ').renplace(/ [ - ] +/g,' - ').replace(/ [^\w-] +/g,'');`而不是选项2.选项2将"th - is"改为"this". (16认同)
  • 请更精致的版本https://gist.github.com/mathewbyrne/1280286 (4认同)
  • 术语"slu"来自wordpress (3认同)

Tar*_*ini 109

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;
};
Run Code Online (Sandbox Code Playgroud)

并尝试

slug($('#field').val())
Run Code Online (Sandbox Code Playgroud)

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


编辑:扩展为更多语言特定的字符:

var from = "ÁÄÂÀÃÅ?Ç??É?ËÈÊ????ÍÌÎÏ??ÑÓÖÒÔÕØ??Š??Ú?ÜÙÛÝŸŽáäâàãå?ç??é?ëèê????íìîï??ñóöòôõøð??š??ú?üùûýÿžþÞ??߯a·/_,:;";
var to   = "AAAAAACCCDEEEEEEEEGIIIIINNOOOOOORRSSTUUUUUYYZaaaaaacccdeeeeeeeegiiiiinnooooooorrsstuuuuuyyzbBDdBAa------";
Run Code Online (Sandbox Code Playgroud)

  • 但不正确.在德语文本中,`ü`应该用'ue`等替换. (6认同)
  • @feklee:"不正确"对于德语(可能还有其他一些语言)是正确的,但在其他语言中它也没关系.对于一个英文网站,我希望将"Márföldi"(匈牙利语的姓氏)转换为"marfoldi",而不是像德国人那样转换为"marfoeldi". (4认同)
  • 不错的解决方案!虽然缺少斯堪的纳维亚语`å`。 (2认同)

Phi*_*ert 18

首先,正则表达式不应该有周围的引号,所以'/\s/g'应该是/\s/g

为了用破折号替换所有非字母数字字符,这应该有效(使用您的示例代码):

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

这应该够了吧...


kar*_*m79 7

所有你需要的是一个加号:)

$("#Restaurant_Name").keyup(function(){
        var Text = $(this).val();
        Text = Text.toLowerCase();
        var regExp = /\s+/g;
        Text = Text.replace(regExp,'-');
        $("#Restaurant_Slug").val(Text);        
});
Run Code Online (Sandbox Code Playgroud)


OXi*_*GEN 7

将此处答案中的各种元素与 normalize 相结合可提供良好的覆盖范围。保持操作顺序以增量清理 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
}
Run Code Online (Sandbox Code Playgroud)

normlize('NFD')将重音字符分解为其组成部分,即基本字母加变音符号(重音部分)。replace(/[\u0300-\u036f]/g, "")清除所有变音符号,单独留下基本字母。其余的用内联注释解释。


Ale*_*nko 6

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

*基于https://gist.github.com/mathewbyrne/1280286

\n\n

现在你可以转换这个字符串:

\n\n
Barack_Obama       \xd0\x91\xd0\xb0\xd1\x80\xd0\xb0\xd0\xba_\xd0\x9e\xd0\xb1\xd0\xb0\xd0\xbc\xd0\xb0 ~!@#$%^&*()+/-+?><:";\'{}[]\\|`\n
Run Code Online (Sandbox Code Playgroud)\n\n

进入:

\n\n
barack_obama-\xd0\xb1\xd0\xb0\xd1\x80\xd0\xb0\xd0\xba_\xd0\xbe\xd0\xb1\xd0\xb0\xd0\xbc\xd0\xb0\n
Run Code Online (Sandbox Code Playgroud)\n\n

适用于您的代码:

\n\n
$("#Restaurant_Name").keyup(function(){\n    var Text = $(this).val();\n    Text = slugify(Text);\n    $("#Restaurant_Slug").val(Text);\n});\n
Run Code Online (Sandbox Code Playgroud)\n


bma*_*ovu 6

希望这可以拯救某人的一天......

/* 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;
}
Run Code Online (Sandbox Code Playgroud)
<input type="text" onload="convertToSlug(this.value)" onkeyup="convertToSlug(this.value)" value="Try it Yourself"/>
<p id="slug-text"></p>
Run Code Online (Sandbox Code Playgroud)


小智 6

注意:如果您不关心反对已接受答案的论点,而只是在寻找答案,请跳过下一部分,您会在最后找到我提出的答案

接受的答案有几个问题(在我看来):

1)至于第一个函数片段:

不考虑多个连续的空格

输入: is it a good slug

已收到: ---is---it---a---good---slug---

预期的: is-it-a-good-slug

不考虑多个连续的破折号

输入: -----is-----it-----a-----good-----slug-----

已收到: -----is-----it-----a-----good-----slug-----

预期的: is-it-a-good-slug

请注意,此实现不处理外部破折号(或与此相关的空格),无论它们是多个连续字符还是单数字符(据我了解 slugs 及其用法)无效

2) 至于第二个函数片段:

它通过将多个连续的空格转换为单个来处理多个连续的空格,-但这还不够,因为外部(在字符串的开头和结尾处)空格的处理方式相同,因此is it a good slug会返回-is-it-a-good-slug-

它还从输入中完全删除了破折号,将诸如--is--it--a--good--slug--'toisitagoodslug之类的东西转换为,@ryan-allen 评论中的代码段处理了这一点,尽管未解决外部破折号问题

现在我知道 slugs 没有标准定义,接受的答案可能会完成工作(发布问题的用户正在寻找),但这是关于 JS 中 slugs 的最流行的 SO 问题,所以这些问题还必须指出,(关于完成工作!)想象一下输入这个令人憎恶的 URL ( www.blog.com/posts/-----how-----to-----slugify-----a-----string-----) 或者甚至只是被重定向到它而不是像 ( www.blog.com/posts/how-to-slugify-a-string)这样的东西,我知道这是一个极端情况,但嘿,这就是测试是给。

在我看来,更好的解决方案如下:

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
Run Code Online (Sandbox Code Playgroud)

现在可能有一个 RegExp ninja 可以将其转换为单行表达式,我不是 RegExp 方面的专家,我并不是说这是最好或最紧凑的解决方案或性能最佳的解决方案但希望它能完成工作。


Max*_*Max 5

看看这个slug函数来清理URL,由Sean Murphy在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 <sean@iamseanmurphy.com>
 * @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;
}
Run Code Online (Sandbox Code Playgroud)


zah*_*d9i 5

我找到了一个很好的英语完整解决方案

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

使用中的一些示例:

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"
Run Code Online (Sandbox Code Playgroud)

感谢安德鲁·斯图尔特