如何在Perl中生成URL slugs?
诸如Rails和Django之类的Web框架内置了对“slugs”的支持,后者用于生成可读和SEO友好的URL:
> Slugs in Rails 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去掉重新组装的“é”后会变得“自由”. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |