加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

如何在Perl中生成URL slugs?

发布时间:2020-12-15 23:35:23 所属栏目:大数据 来源:网络整理
导读:诸如Rails和Django之类的Web框架内置了对“slugs”的支持,后者用于生成可读和SEO友好的URL: Slugs in Rails Slugs in Django slug字符串通常只包含字符a-z,0-9和 – 因此可以在没有URL转义的情况下编写(想想“foo bar”). 我正在寻找一个Perl slug函数,给出
诸如Rails和Django之类的Web框架内置了对“slugs”的支持,后者用于生成可读和SEO友好的URL:

> Slugs in Rails
> Slugs in Django

slug字符串通常只包含字符a-z,0-9和 – 因此可以在没有URL转义的情况下编写(想想“foo bar”).

我正在寻找一个Perl slug函数,给出任何有效的Unicode字符串将返回一个slug表示(a-z,0-9和 – ).

一个超级微不足道的slug功能将是这样的:

$input = lc($input),$input =~ s/[^a-z0-9-]//g;

但是,这种实现不会处理国际化和口音(我想要成为e).解决这个问题的一种方法是列举所有特殊情况,但这不是很优雅.我正在寻找更好的思考和一般的东西.

我的问题:

>在Perl中生成Django / Rails类型slugs的最通用/最实用的方法是什么? This是我在Java中解决同样问题的方法.

解决方法

目前在Django中使用的 slugify filter(大致)转换为以下Perl代码:

use Unicode::Normalize;

sub slugify($) {
    my ($input) = @_;

    $input = NFKD($input);         # Normalize (decompose) the Unicode string
    $input =~ tr/00-177//cd;    # Strip non-ASCII characters (>127)
    $input =~ s/[^ws-]//g;       # Remove all characters that are not word characters (includes _),spaces,or hyphens
    $input =~ s/^s+|s+$//g;      # Trim whitespace from both ends
    $input = lc($input);
    $input =~ s/[-s]+/-/g;        # Replace all occurrences of spaces and hyphens with a single hyphen

    return $input;
}

由于您还想将重音字符更改为不重音字符,因此在剥离非ASCII字符之前抛出对unidecode的调用(在Text :: Unidecode中定义)似乎是您最好的选择(as pointed out by phaylon).

在这种情况下,该功能可能如下所示:

use Unicode::Normalize;
use Text::Unidecode;

sub slugify_unidecode($) {
    my ($input) = @_;

    $input = NFC($input);          # Normalize (recompose) the Unicode string
    $input = unidecode($input);    # Convert non-ASCII characters to closest equivalents
    $input =~ s/[^ws-]//g;       # Remove all characters that are not word characters (includes _),or hyphens
    $input =~ s/^s+|s+$//g;      # Trim whitespace from both ends
    $input = lc($input);
    $input =~ s/[-s]+/-/g;        # Replace all occurrences of spaces and hyphens with a single hyphen

    return $input;
}

前者适用于主要是ASCII的字符串,但是当整个字符串由非ASCII字符组成时,它们会很短,因为它们都被剥离,留下一个空字符串.

样本输出:

string        | slugify       | slugify_unidecode
-------------------------------------------------
hello world     hello world     hello world
北亰                            bei-jing
liberté         liberta         liberte

请注意,基于Django的实现,北how如何变得虚无…还要注意NFC标准化所带来的差异 – 在剥离分解后的角色的第二部分后,liberté变成了NFKD的“自由”,但在用NFC去掉重新组装的“é”后会变得“自由”.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读