JavaScript Slug也适用于非拉丁字符吗?

4
基本上,我找到了一个看起来像这样的“slug”函数:
function slug(string) => { 
    return string.toString().toLowerCase()
        .replace(/\s+/g, '-')
        .replace(/[^\w\-]+/g, '')
        .replace(/\-\-+/g, '-')
        .replace(/^-+/, '')
        .replace(/-+$/, '');
};

然而,在处理俄语、希腊等字符时,似乎不起作用。基本上,在此步骤中它们被删除:.replace(/[^\w\-]+/g, ''),但我不想这样做,同时我也想删除其他一些在某些国家并不代表正常字母的特殊字符。
示例:
英文 | 你知道下雨了吗? | do-you-know-it-rains
捷克文 | víš, že prší? | vis-ze-prsi
罗马尼亚文 | Ști că plouă? | sti-ca-ploua
俄文 | ты знаешь, что идет дождь?| ты-знаешь-что-идет-дождь
注意:
基本上对于拉丁字母表,我会保留字母,但去除变音符号。但对于非拉丁字母表,我将保留原样(不想将其转换为拉丁字符)。

参见:https://dev59.com/gmYr5IYBdhLWcg3w6OGd - cmbuckley
1个回答

9

这里有一种方法可以处理特殊字符。使用一组对象,您可以将要替换的每个特殊字符归类到将替换它的拉丁字符下面。

但是,为了保留希腊和俄罗斯字符不受影响,您必须使用正则表达式将其视为单词字符。因此,在使用上述技巧替换特殊字符后,您必须使用以下正则表达式[^-a-zа-я\u0370-\u03ff\u1f00-\u1fff] 删除所有非单词字符。

该正则表达式包括破折号,拉丁字符 a-z 接着是西里尔字母 а-я,最后是扩展的Unicode范围 \u0370-\u03ff\u1f00-\u1fff, 它包含了希腊字符.

您可以使用这个 维基百科语言识别表 来添加更多特殊字符到集合中。

function slugify(text) {
  text = text.toString().toLowerCase().trim();

  const sets = [
    {to: 'a', from: '[ÀÁÂÃÄÅÆĀĂĄẠẢẤẦẨẪẬẮẰẲẴẶἀ]'},
    {to: 'c', from: '[ÇĆĈČ]'},
    {to: 'd', from: '[ÐĎĐÞ]'},
    {to: 'e', from: '[ÈÉÊËĒĔĖĘĚẸẺẼẾỀỂỄỆ]'},
    {to: 'g', from: '[ĜĞĢǴ]'},
    {to: 'h', from: '[ĤḦ]'},
    {to: 'i', from: '[ÌÍÎÏĨĪĮİỈỊ]'},
    {to: 'j', from: '[Ĵ]'},
    {to: 'ij', from: '[IJ]'},
    {to: 'k', from: '[Ķ]'},
    {to: 'l', from: '[ĹĻĽŁ]'},
    {to: 'm', from: '[Ḿ]'},
    {to: 'n', from: '[ÑŃŅŇ]'},
    {to: 'o', from: '[ÒÓÔÕÖØŌŎŐỌỎỐỒỔỖỘỚỜỞỠỢǪǬƠ]'},
    {to: 'oe', from: '[Œ]'},
    {to: 'p', from: '[ṕ]'},
    {to: 'r', from: '[ŔŖŘ]'},
    {to: 's', from: '[ߌŜŞŠȘ]'},
    {to: 't', from: '[ŢŤ]'},
    {to: 'u', from: '[ÙÚÛÜŨŪŬŮŰŲỤỦỨỪỬỮỰƯ]'},
    {to: 'w', from: '[ẂŴẀẄ]'},
    {to: 'x', from: '[ẍ]'},
    {to: 'y', from: '[ÝŶŸỲỴỶỸ]'},
    {to: 'z', from: '[ŹŻŽ]'},
    {to: '-', from: '[·/_,:;\']'}
  ];

  sets.forEach(set => {
    text = text.replace(new RegExp(set.from,'gi'), set.to)
  });

  return text
    .replace(/\s+/g, '-')    // Replace spaces with -
    .replace(/[^-a-zа-я\u0370-\u03ff\u1f00-\u1fff]+/g, '') // Remove all non-word chars
    .replace(/--+/g, '-')    // Replace multiple - with single -
    .replace(/^-+/, '')      // Trim - from start of text
    .replace(/-+$/, '')      // Trim - from end of text
}

console.log(slugify('Do you know it rains?'));
console.log(slugify('víš, že prší?'));
console.log(slugify('Ști că plouă?'));
console.log(slugify('ты знаешь, что идет дождь?'));
console.log(slugify('ἀεὶ Λιβύη φέρει τι καινόν'));


你好,感谢你的工作和回答。也许我表达得不够清楚。基本上,对于俄语,我想在URL中保留他们的字母。我只想从拉丁字母中删除变音符号。所以基本上我想把 ă 转换成 a,但是我想保留 Б 这样的字母。(漂亮的URL,这样俄罗斯人可以更好地理解URL) - paulalexandru
不,实际上它不起作用,请检查。非拉丁文字已被剥离。 - paulalexandru
你好,感谢您的帮助。我现在会立即检查您的答案并回复。所以基本上这个东西就是起作用的,对吗?[^а-яα-ωa-z-]+ 基本上它考虑了希腊、俄罗斯和拉丁字符,对吗? - paulalexandru
是的,一个用于拉丁字符的范围,一个用于希腊字符,还有一个用于俄语字符。我也添加了一个希腊字母的示例,并去掉了重音。 - jo_va
“ἀεὶ Λιβύη φέρει τι καινόν” 这个被转换成了 “ε-λιβη-φρει-τι-καινν”,我不确定这是否正确。 - paulalexandru
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接