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

发布于 2024-07-26 10:18:25 字数 417 浏览 6 评论 0原文

我正在 CodeIgniter 中开发一个应用程序,并且尝试在表单上创建一个字段来动态生成 URL slug。 我想做的是删除标点符号,将其转换为小写,然后用连字符替换空格。 例如,Shane's 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);  
});

I'm working on an app in CodeIgniter, and I'm trying to make a field on a form dynamically generate the URL slug. What I'd like to do is remove the punctuation, convert it to lowercase, and replace the spaces with hyphens. So for example, Shane's Rib Shack would become shanes-rib-shack.

Here's what I have so far. The lowercase part was easy, but the replace doesn't seem to be working at all, and I have no idea to remove the punctuation:

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(28

┊风居住的梦幻卍 2024-08-02 10:18:26

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

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

All you needed was a plus :)

$("#Restaurant_Name").keyup(function() {
  var Text = $(this).val();
  Text = Text.toLowerCase();
  var regExp = /\s+/g;
  Text = Text.replace(regExp,'-');
  $("#Restaurant_Slug").val(Text);        
});
稚气少女 2024-08-02 10:18:26

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

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

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

不考虑多个连续的空格

输入:它是一个好的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

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

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

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

它还会从输入中完全删除破折号将 --is--it--a--good--slug--' 转换为 isitagoodslug ,@ryan-allen 评论中的代码片段会照顾到其中,外部破折号问题尚未解决,尽管

现在我知道没有标准定义,并且接受的答案可能会完成工作(发布问题的用户正在寻找的工作),但这是最受欢迎的关于 JS 中的 slugs 的问题,所以必须指出这些问题(关于完成工作!)想象一下输入这个令人厌恶的 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

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

Note: if you don't care about an argument against the accepted answer and are just looking for an answer, then skip next section, you'll find my proposed answer at the end

the accepted answer has a few issues (in my opinion):

1) as for the first function snippet:

no regard for multiple consecutive whitespaces

input: is it a good slug

received: ---is---it---a---good---slug---

expected: is-it-a-good-slug

no regard for multiple consecutive dashes

input: -----is-----it-----a-----good-----slug-----

received: -----is-----it-----a-----good-----slug-----

expected: is-it-a-good-slug

please note that this implementation doesn't handle outer dashes (or whitespaces for that matter) whether they are multiple consecutive ones or singular characters which (as far as I understand slugs, and their usage) is not valid

2) as for the second function snippet:

it takes care of the multiple consecutive whitespaces by converting them to single - but that's not enough as outer (at the start and end of the string) whitespaces are handled the same, so is it a good slug would return -is-it-a-good-slug-

it also removes dashes altogether from the input which converts something like --is--it--a--good--slug--' to isitagoodslug , the snippet in the comment by @ryan-allen takes care of that, leaving the outer dashes issue unsolved though

now I know that there is no standard definition for slugs, and the accepted answer may get the job (that the user who posted the question was looking for) done, but this is the most popular SO question about slugs in JS, so those issues had to be pointed out, also (regarding getting the job done!) imagine typing this abomination of a URL (www.blog.com/posts/-----how-----to-----slugify-----a-----string-----) or even just be redirected to it instead of something like (www.blog.com/posts/how-to-slugify-a-string), I know this is an extreme case but hey that's what tests are for.

a better solution, in my opinion, would be as follows:

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

now there is probably a RegExp ninja out there that can convert this into a one-liner expression, I'm not an expert in RegExp and I'm not saying that this is the best or most compact solution or the one with the best performance but hopefully it can get the job done.

﹎☆浅夏丿初晴 2024-08-02 10:18:26
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
}

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

现在你可以转换它string:

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

into:

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

应用于您的代码:

$("#Restaurant_Name").keyup(function(){
    var Text = $(this).val();
    Text = slugify(Text);
    $("#Restaurant_Slug").val(Text);
});
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
}

*based on https://gist.github.com/mathewbyrne/1280286

now you can transform this string:

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

into:

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

applying to your code:

$("#Restaurant_Name").keyup(function(){
    var Text = $(this).val();
    Text = slugify(Text);
    $("#Restaurant_Slug").val(Text);
});
鹤仙姿 2024-08-02 10:18:26

我创建了一个在大多数语言中实现的插件:http://leocaseiro。 com.br/jquery-plugin-string-to-slug/

默认用法:

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

非常简单有 stringToSlug jQuery 插件

I create a plugin to implement in most of languages: http://leocaseiro.com.br/jquery-plugin-string-to-slug/

Default Usage:

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

Is very easy has stringToSlug jQuery Plugin

江湖彼岸 2024-08-02 10:18:26

对于已经使用 lodash 的人

这些示例中的大多数都非常好并且涵盖了很多案例。 但如果你“知道”你只有英文文本,这是我的版本,非常容易阅读:)

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

For people already using lodash

Most of these example are really good and cover a lot of cases. But if you 'know' that you only have English text, here's my version that's super easy to read :)

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

划一舟意中人 2024-08-02 10:18:26
function slugify(content) {
   return content.toLowerCase().replace(/ /g,'-').replace(/[^\w-]+/g,'');
}
// slugify('Hello World');
// this will return 'hello-world';

这对我来说很好。

CodeSnipper

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

this works for me fine.

Found it on CodeSnipper

美人如玉 2024-08-02 10:18:26
$("#Restaurant_Name").keyup(function() {
  var Text = $(this).val();
  Text = Text.toLowerCase();
  Text = Text.replace(/[^a-zA-Z0-9]+/g,'-');
  $("#Restaurant_Slug").val(Text);        
});

这段代码正在运行

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

This code is working

女中豪杰 2024-08-02 10:18:26

好吧,读完答案后,我想出了这个。

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

Well, after reading the answers, I came up with this one.

const generateSlug = (text) => text.toLowerCase()
                                   .trim()
                                   .replace(/[^\w- ]+/g, '')
                                   .replace(/ /g, '-')
                                   .replace(/[-]+/g, '-');
撩人痒 2024-08-02 10:18:26

您可以为此使用自己的函数。

尝试一下: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;
    });
});

You can use your own function for this.

try it: 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;
    });
});
浮云落日 2024-08-02 10:18:26

您可能想看看 speakingURL 插件,然后您就可以:

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

You may want to take a look at the speakingURL plugin and then you just could:

    $("#Restaurant_Name").on("keyup", function () {
        var slug = getSlug($("#Restaurant_Name").val());
        $("#Restaurant_Slug").val(slug);
    });
小女人ら 2024-08-02 10:18:26

纯 JavaScript 上更强大的 slug 生成方法。 它基本上支持所有西里尔字符和许多元音变音(德语、丹麦语、法国、土耳其语、乌克兰语等)的音译,但可以轻松扩展。

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 = [/( | | )/gi, /(—|–|‑)/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 &
  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/> ‪Про&вер<strong>ка_тран</strong>с…литеърьации\rюга\nи–южного округа\t \nс\tёжикам´и со\\всеми–друзьями\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>

More powerful slug generation method on pure JavaScript. It's basically support transliteration for all Cyrillic characters and many Umlauts (German, Danish, France, Turkish, Ukrainian and etc.) but can be easily extended.

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 = [/( | | )/gi, /(—|–|‑)/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 &
  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/> ‪Про&вер<strong>ка_тран</strong>с…литеърьации\rюга\nи–южного округа\t \nс\tёжикам´и со\\всеми–друзьями\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>

巷子口的你 2024-08-02 10:18:26

接受的答案不满足我的需求(它允许下划线,不处理开头和结尾的破折号等),其他答案还有其他不适合我的用例的问题,所以这是 slugify 函数我想出了:

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.
}

这会将“foo!!!BAR_-_-_baz-”(注意开头的空格)变成foo-bar-baz

The accepted answer didn't meet my needs (it allows underscores, doesn't handle dashes at the beginning and end, etc.), and the other answers had other issues that didn't suit my use case, so here's the slugify function I came up with:

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.
}

This will turn ' foo!!!BAR_-_-_baz-' (note the space at the beginning) into foo-bar-baz.

瞎闹 2024-08-02 10:18:26

还有一个。 简短并保留特殊字符:

imaginação é 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
}

Yet another one. Short and keeps special characters:

imaginação é mato => imaginacao-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
}
风筝在阴天搁浅。 2024-08-02 10:18:26

有一天,我醒来,想用 javascript 编写一个完美的 slugify 函数,该函数将提供与 Wordpress 清理标题相同的结果(多么糟糕的名字,清理标题,顺便说一句),然后继续与我的生命。

我四处窥探,看到了很多解决方案(可能没有特殊原因就太复杂了),修改了我多年来使用的解决方案(太简单并且浪费了很多时间)。 我也研究过Wordpress代码,没有评论。

我还找到了 Sal 的帖子。 他的代码很酷,但对我来说太复杂了。 最重要的是,他的帖子包含一个非常重要的东西,他用于测试的数据表

所以我坐下来想出了这个:

function slugify(str) {
  str = str.trim().toLowerCase()
  // Remove accents
  str = str.normalize('NFD').replace(/[\u0300-\u036f]/g, '').replace(/\œ/g, "oe").replace(/\æ/g, "ae").normalize('NFC')
  // Strip html tags
  str = str.replace(/<[^>]*>/g, '')
  return str.replace(/\s+|\.+|\/+|\\+|—+|–+/g, '-').replace(/[^\w0-9\-]+/g, '').replace(/-{2,}/g, '-').replace(/^-|-$/g, '')
}

通过 Jest 使用我从 Sal 中提取的数据集进行验证发布。

您可以在小提琴 https://jsfiddle.net/stamat/vq14dL5z/ 中查看它的功能

您可以在我的小型 ESM 库中找到此函数 https://github.com/stamat /book-of-spells 采用 NPM/YARN 包 book-of-spells 的形式。 这是我的 JS 片段库,如果您认为合适,请贡献并随意使用其中的任何部分!

感谢 Sal Ferrarello 和你们所有人提供的小线索并帮助我提出解决方案。 感谢大家!

One day I woke up and I wanted to write of a perfect slugify function in javascript that will provide the same result as Wordpress sanitize title (what a terrible name, sanitize title, btw), and just get on with my life.

I've snooped around, seen a lot of solutions (which are maybe too complex for no particular reason), revised my solution that I was using for years (which was too simple and sucked big time). I've also looked into Wordpress code, no comment.

I've also found the Sal's post. His code was cool but too complex for my taste. Most importantly his post contained one very important thing, a table of data that he used for testing.

So I sat down and came up with this:

function slugify(str) {
  str = str.trim().toLowerCase()
  // Remove accents
  str = str.normalize('NFD').replace(/[\u0300-\u036f]/g, '').replace(/\œ/g, "oe").replace(/\æ/g, "ae").normalize('NFC')
  // Strip html tags
  str = str.replace(/<[^>]*>/g, '')
  return str.replace(/\s+|\.+|\/+|\\+|—+|–+/g, '-').replace(/[^\w0-9\-]+/g, '').replace(/-{2,}/g, '-').replace(/^-|-$/g, '')
}

Validating it through Jest with a data set I've extracted from Sal's post.

You can see it in function in the fiddle https://jsfiddle.net/stamat/vq14dL5z/

You can find this function as a part of my small ESM library https://github.com/stamat/book-of-spells in form of a NPM/YARN package book-of-spells. It's a library of my JS snippets, please do contribute if you see fit and feel free to use any part of it!

Thanks to Sal Ferrarello and all of you for providing little clues and helping me come up with my solution. Thanks everyone!

病女 2024-08-02 10:18:26
//
//  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;
    };

这帮助我解决了同样的问题!

//
//  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;
    };

This helped me with the same problem !

霓裳挽歌倾城醉 2024-08-02 10:18:26
String.prototype.slug = function(e='-'){
  let $this=this
        .toUpperCase()
        .toLowerCase()
        .normalize('NFD')
        .trim()
        .replace(/\s+/g,e)
        .replace(/-\+/g,'')
        .replace(/-+/g,e)
        .replace(/^-/g,'')
        .replace(/-$/g,'')
        .replace(/[^\w-]/g,'');
  return $this
        .toUpperCase()
        .toLowerCase()
        .normalize('NFD')
        .trim()
        .replace(/\s+/g,e)
        .replace(/-\+/g,'')
        .replace(/-+/g,e)
        .replace(/^-/g,'')
        .replace(/-$/g,'')
        .replace(/[^\w-]/g,'');
}

我过滤了两次,因为由于一些不需要的字符,可以放入更多 -

String.prototype.slug = function(e='-'){
  let $this=this
        .toUpperCase()
        .toLowerCase()
        .normalize('NFD')
        .trim()
        .replace(/\s+/g,e)
        .replace(/-\+/g,'')
        .replace(/-+/g,e)
        .replace(/^-/g,'')
        .replace(/-$/g,'')
        .replace(/[^\w-]/g,'');
  return $this
        .toUpperCase()
        .toLowerCase()
        .normalize('NFD')
        .trim()
        .replace(/\s+/g,e)
        .replace(/-\+/g,'')
        .replace(/-+/g,e)
        .replace(/^-/g,'')
        .replace(/-$/g,'')
        .replace(/[^\w-]/g,'');
}

I filtered it twice because more - could be put in because of some unwanted characters

你怎么这么可爱啊 2024-08-02 10:18:26

塔兰蒂尼答案的扩展版本 - https://stackoverflow.com/a/5782563/14431043

var from = "ªºÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõöøùúûüýþÿØĀāĂ㥹ĆćĈĉĊċČčĎďĐđĒēĔĕĖėĘęĚěĜĝĞğĠġĢģĤĥĦħĨĩĪīĬĭĮįİıIJijĴĵĶķĸĹĺĻļĽľĿŀŁłŃńŅņŇňʼnŊŋŌōŎŏŐőŒœŔŕŖŗŘřŚśŜŝŞşŠšŢţŤťŦŧŨũŪūŬŭŮůŰűŲųŴŵŶŷŸŹźŻżŽžſȘșȚț€£OơƯưẦầẰằỀềỒồỜờỪừỲỳẢảẨẩẲẳẺẻỂểỈỉỎỏỔổỞởỦủỬửỶỷẪẫẴẵẼẽỄễỖỗỠỡỮữỸỹẤấẮắẾếỐốỚớỨứẠạẬậẶặẸẹỆệỊịỌọỘộỢợỤụỰựỴỵɑǕǖǗǘǍǎǏǐǑǒǓǔǙǚǛǜ·/_,:;";
var to = "aoAAAAAAACEEEEIIIIDNOOOOOUUUUYTsaaaaaaaceeeeiiiidnoooooouuuuytyOAaAaAaCcCcCcCcDdDdEeEeEeEeEeGgGgGgGgHhHhIiIiIiIiIiIiJjKkkLlLlLlLlLlNnNnNnnNnOoOoOoOoRrRrRrSsSsSsSsTtTtTtUuUuUuUuUuUuWwYyYZzZzZzsSsTtE--oUuAaAaEeOoOoUuYyAaAaAaEeEeIiOoOoOoUuUuYyAaAaEeEeOoOoUuYyAaAaEeOoOoUuAaAaAaEeEeIiOoOoOoUuUuYyaUuUuAaIiOoUuUuUu------";

A bit extended version of Taranttini answer - https://stackoverflow.com/a/5782563/14431043

var from = "ªºÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõöøùúûüýþÿØĀāĂ㥹ĆćĈĉĊċČčĎďĐđĒēĔĕĖėĘęĚěĜĝĞğĠġĢģĤĥĦħĨĩĪīĬĭĮįİıIJijĴĵĶķĸĹĺĻļĽľĿŀŁłŃńŅņŇňʼnŊŋŌōŎŏŐőŒœŔŕŖŗŘřŚśŜŝŞşŠšŢţŤťŦŧŨũŪūŬŭŮůŰűŲųŴŵŶŷŸŹźŻżŽžſȘșȚț€£OơƯưẦầẰằỀềỒồỜờỪừỲỳẢảẨẩẲẳẺẻỂểỈỉỎỏỔổỞởỦủỬửỶỷẪẫẴẵẼẽỄễỖỗỠỡỮữỸỹẤấẮắẾếỐốỚớỨứẠạẬậẶặẸẹỆệỊịỌọỘộỢợỤụỰựỴỵɑǕǖǗǘǍǎǏǐǑǒǓǔǙǚǛǜ·/_,:;";
var to = "aoAAAAAAACEEEEIIIIDNOOOOOUUUUYTsaaaaaaaceeeeiiiidnoooooouuuuytyOAaAaAaCcCcCcCcDdDdEeEeEeEeEeGgGgGgGgHhHhIiIiIiIiIiIiJjKkkLlLlLlLlLlNnNnNnnNnOoOoOoOoRrRrRrSsSsSsSsTtTtTtUuUuUuUuUuUuWwYyYZzZzZzsSsTtE--oUuAaAaEeOoOoUuYyAaAaAaEeEeIiOoOoOoUuUuYyAaAaEeEeOoOoUuYyAaAaEeOoOoUuAaAaAaEeEeIiOoOoOoUuUuYyaUuUuAaIiOoUuUuUu------";
卸妝后依然美 2024-08-02 10:18:26
<!DOCTYPE html>

<html>

<head>

    <style>

        fieldset.slugify {
            color: #515151;
            border: 1px solid #ccc;
            padding: 15px;
        }

        .slugify legend {
            font-size: 16px;
            font-weight: 600;
            padding: 0 10px;
        }

        .slugify input {
            display: block;
            padding: 8px;
            margin: 8px;
        }

        .slug-output {
            color: #05ab13;
            font-size: 20px;
            font-weight: 500;
        }

    </style>

</head>
 
<body>

    <form>

        <fieldset class="slugify">

            <legend>GeeksforGeeks</legend>

            <label for="slug-source">Input Title: </label>

            <input type="text" value="" id="slug-source" onkeyup="myFunction()" />

            <label for="slug-target">URL Slug: </label>

            <input type="text" value="" id="slug-target" />

            <button type="button" >

                Convert
            </button>       
    
            <p>

                <span class="slug-output">
                    Generated URL Slug
                </span>:

                <span id="slug-target-span"></span>

            </p>

        </fieldset>

    </form>

<script>

    function myFunction() {

        var a = document.getElementById("slug-source").value;

        var b = a.toLowerCase().replace(/ /g, '-')

            .replace(/[^\w-]+/g, '');

        document.getElementById("slug-target").value = b;

        document.getElementById("slug-target-span").innerHTML = b;

    }

</script>

</body>
 
</html>
<!DOCTYPE html>

<html>

<head>

    <style>

        fieldset.slugify {
            color: #515151;
            border: 1px solid #ccc;
            padding: 15px;
        }

        .slugify legend {
            font-size: 16px;
            font-weight: 600;
            padding: 0 10px;
        }

        .slugify input {
            display: block;
            padding: 8px;
            margin: 8px;
        }

        .slug-output {
            color: #05ab13;
            font-size: 20px;
            font-weight: 500;
        }

    </style>

</head>
 
<body>

    <form>

        <fieldset class="slugify">

            <legend>GeeksforGeeks</legend>

            <label for="slug-source">Input Title: </label>

            <input type="text" value="" id="slug-source" onkeyup="myFunction()" />

            <label for="slug-target">URL Slug: </label>

            <input type="text" value="" id="slug-target" />

            <button type="button" >

                Convert
            </button>       
    
            <p>

                <span class="slug-output">
                    Generated URL Slug
                </span>:

                <span id="slug-target-span"></span>

            </p>

        </fieldset>

    </form>

<script>

    function myFunction() {

        var a = document.getElementById("slug-source").value;

        var b = a.toLowerCase().replace(/ /g, '-')

            .replace(/[^\w-]+/g, '');

        document.getElementById("slug-target").value = b;

        document.getElementById("slug-target-span").innerHTML = b;

    }

</script>

</body>
 
</html>
瞳孔里扚悲伤 2024-08-02 10:18:26

这是实际的解决方案

text.replace(/\./g, ' ').trim().toLowerCase().replace(/ /g,'-').replace(/[-]+/g, '-').replace(/[^\w-]+/g,'');

This is the actual solutions

text.replace(/\./g, ' ').trim().toLowerCase().replace(/ /g,'-').replace(/[-]+/g, '-').replace(/[^\w-]+/g,'');
长伴 2024-08-02 10:18:26
document.addEventListener('DOMContentLoaded', function() {
        function generateSlug(value) {
            return value
                .toString()
                .toLowerCase()
                .replace(/\s+/g, '-')           // Replace spaces with -
                .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
        }

        const restaurantNameInput = document.getElementById('restaurant_name');
        const subdomainInput = document.getElementById('subdomain');

        if (restaurantNameInput && subdomainInput) {
            restaurantNameInput.addEventListener('input', function() {
                let restaurantName = this.value;
                let slug = generateSlug(restaurantName);
                subdomainInput.value = slug;
            });
        } else {
            console.error('Restaurant name input or subdomain input not found.');
        }
    });
document.addEventListener('DOMContentLoaded', function() {
        function generateSlug(value) {
            return value
                .toString()
                .toLowerCase()
                .replace(/\s+/g, '-')           // Replace spaces with -
                .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
        }

        const restaurantNameInput = document.getElementById('restaurant_name');
        const subdomainInput = document.getElementById('subdomain');

        if (restaurantNameInput && subdomainInput) {
            restaurantNameInput.addEventListener('input', function() {
                let restaurantName = this.value;
                let slug = generateSlug(restaurantName);
                subdomainInput.value = slug;
            });
        } else {
            console.error('Restaurant name input or subdomain input not found.');
        }
    });
顾铮苏瑾 2024-08-02 10:18:26
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();
}
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();
}
平安喜乐 2024-08-02 10:18:25

我不知道“蛞蝓”一词从何而来,但我们开始吧:

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

console.log(convertToSlug("hello world!"));
console.log(convertToSlug("hello - world!"));

第一个 replace 方法会将空格更改为连字符,第二个,replace 会删除除字母数字、下划线或连字符之外的所有内容。

如果你不希望“like - this”变成“like---this”,那么你可以使用这个:

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

console.log(convertToSlug("hello world!"));
console.log(convertToSlug("hello - world!"));

这将在第一次替换时删除连字符(但没有空格),在第二次替换中它将把连续的空格压缩为单个连字符。

所以“like - this”就变成了“like-this”。

I have no idea where the 'slug' term came from, but here we go:

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

console.log(convertToSlug("hello world!"));
console.log(convertToSlug("hello - world!"));

The first replace method will change spaces to hyphens, second, replace removes anything not alphanumeric, underscore, or hyphen.

If you don't want things "like - this" turning into "like---this" then you can instead use this one:

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

console.log(convertToSlug("hello world!"));
console.log(convertToSlug("hello - world!"));

That will remove hyphens (but no spaces) on the first replace, and in the second replace it will condense consecutive spaces into a single hyphen.

So "like - this" comes out as "like-this".

瑶笙 2024-08-02 10:18:25
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;
};

并尝试

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

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


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

var from = "ÁÄÂÀÃÅČÇĆĎÉĚËÈÊẼĔȆĞÍÌÎÏİŇÑÓÖÒÔÕØŘŔŠŞŤÚŮÜÙÛÝŸŽáäâàãåčçćďéěëèêẽĕȇğíìîïıňñóöòôõøðřŕšşťúůüùûýÿžþÞĐđßÆa·/_,:;";
var to   = "AAAAAACCCDEEEEEEEEGIIIIINNOOOOOORRSSTUUUUUYYZaaaaaacccdeeeeeeeegiiiiinnooooooorrsstuuuuuyyzbBDdBAa------";
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;
};

and try

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

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


EDIT:
extended for more language specific chars:

var from = "ÁÄÂÀÃÅČÇĆĎÉĚËÈÊẼĔȆĞÍÌÎÏİŇÑÓÖÒÔÕØŘŔŠŞŤÚŮÜÙÛÝŸŽáäâàãåčçćďéěëèêẽĕȇğíìîïıňñóöòôõøðřŕšşťúůüùûýÿžþÞĐđßÆa·/_,:;";
var to   = "AAAAAACCCDEEEEEEEEGIIIIINNOOOOOORRSSTUUUUUYYZaaaaaacccdeeeeeeeegiiiiinnooooooorrsstuuuuuyyzbBDdBAa------";
蓝戈者 2024-08-02 10:18:25

首先,正则表达式不应该有引号,所以 '/\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);        
});

这应该可以解决问题......

First of all, regular expressions should not have surrounding quotes, so '/\s/g' should be /\s/g

In order to replace all non-alphanumerical characters with dashes, this should work (using your example code):

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

That should do the trick...

内心荒芜 2024-08-02 10:18:25

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

/* 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>

Hope this can save someone's day...

/* 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>

守护在此方 2024-08-02 10:18:25

将此处答案中的各种元素与标准化相结合可以提供良好的覆盖范围。 保持操作顺序以增量清理 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') 将重音字符分解为其组成部分,即基本字母加上变音符号(重音部分)。 replace(/[\u0300-\u036f]/g, "") 清除所有变音符号,保留基本字母本身。 其余部分通过内联注释进行解释。

Combining a variety of elements from the answers here with normalize provides good coverage. Keep the order of operations to incrementally clean the 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') breaks accented characters into their components, which are basic letters plus diacritics (the accent part). replace(/[\u0300-\u036f]/g, "") purges all the diacritics, leaving the basic letters by themselves. The rest is explained with inline comments.

维持三分热 2024-08-02 10:18:25

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

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

它的一些使用示例:

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"

感谢 Andrew Stewart

I found a good and complete solution for English

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

Some examples of it in use:

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"

Thanks to Andrew Stewart

百变从容 2024-08-02 10:18:25

看一下这个 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 <[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;
}

Take a look at this slug function to sanitize URLs, developed by Sean Murphy at 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;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文