标签归档:collation

如何在Python中按字母顺序对unicode字符串排序?

问题:如何在Python中按字母顺序对unicode字符串排序?

Python默认情况下按字节值排序,这意味着é在z和其他同样有趣的事情之后。在Python中按字母顺序排序的最佳方法是什么?

有图书馆吗?我什么都找不到。最好是排序应该有语言支持,因此它理解åäö应该用瑞典语在z之后排序,但是ü应该用u进行排序,依此类推。因此,Unicode支持非常必要。

如果没有它的库,什么是最好的方法?只需将字母映射到整数值,然后将字符串映射到整数列表?

Python sorts by byte value by default, which means é comes after z and other equally funny things. What is the best way to sort alphabetically in Python?

Is there a library for this? I couldn’t find anything. Preferrably sorting should have language support so it understands that åäö should be sorted after z in Swedish, but that ü should be sorted by u, etc. Unicode support is thereby pretty much a requirement.

If there is no library for it, what is the best way to do this? Just make a mapping from letter to a integer value and map the string to a integer list with that?


回答 0

IBM的ICU库可以做到这一点(还有更多)。它具有Python绑定:PyICU

更新:在ICU之间进行排序的核心区别locale.strcoll在于,ICU使用完整的Unicode排序算法,strcoll使用ISO 14651

此处简要总结了这两种算法之间的区别:http : //unicode.org/faq/collat​​ion.html#13。这些是非常奇特的特殊情况,在实践中几乎没有关系。

>>> import icu # pip install PyICU
>>> sorted(['a','b','c','ä'])
['a', 'b', 'c', 'ä']
>>> collator = icu.Collator.createInstance(icu.Locale('de_DE.UTF-8'))
>>> sorted(['a','b','c','ä'], key=collator.getSortKey)
['a', 'ä', 'b', 'c']

IBM’s ICU library does that (and a lot more). It has Python bindings: PyICU.

Update: The core difference in sorting between ICU and locale.strcoll is that ICU uses the full Unicode Collation Algorithm while strcoll uses ISO 14651.

The differences between those two algorithms are briefly summarized here: http://unicode.org/faq/collation.html#13. These are rather exotic special cases, which should rarely matter in practice.

>>> import icu # pip install PyICU
>>> sorted(['a','b','c','ä'])
['a', 'b', 'c', 'ä']
>>> collator = icu.Collator.createInstance(icu.Locale('de_DE.UTF-8'))
>>> sorted(['a','b','c','ä'], key=collator.getSortKey)
['a', 'ä', 'b', 'c']

回答 1

我没有在答案中看到这一点。我的应用程序使用python的标准库根据语言环境进行排序。这很容易。

# python2.5 code below
# corpus is our unicode() strings collection as a list
corpus = [u"Art", u"Älg", u"Ved", u"Wasa"]

import locale
# this reads the environment and inits the right locale
locale.setlocale(locale.LC_ALL, "")
# alternatively, (but it's bad to hardcode)
# locale.setlocale(locale.LC_ALL, "sv_SE.UTF-8")

corpus.sort(cmp=locale.strcoll)

# in python2.x, locale.strxfrm is broken and does not work for unicode strings
# in python3.x however:
# corpus.sort(key=locale.strxfrm)

给Lennart和其他回答者的问题:没有人知道“语言环境”吗?还是不符合这项任务?

I don’t see this in the answers. My Application sorts according to the locale using python’s standard library. It is pretty easy.

# python2.5 code below
# corpus is our unicode() strings collection as a list
corpus = [u"Art", u"Älg", u"Ved", u"Wasa"]

import locale
# this reads the environment and inits the right locale
locale.setlocale(locale.LC_ALL, "")
# alternatively, (but it's bad to hardcode)
# locale.setlocale(locale.LC_ALL, "sv_SE.UTF-8")

corpus.sort(cmp=locale.strcoll)

# in python2.x, locale.strxfrm is broken and does not work for unicode strings
# in python3.x however:
# corpus.sort(key=locale.strxfrm)

Question to Lennart and other answerers: Doesn’t anyone know ‘locale’ or is it not up to this task?


回答 2

尝试使用James Tauber的Python Unicode排序规则算法。它可能无法完全满足您的要求,但似乎值得一看。有关这些问题的更多信息,请参阅Christopher Lenz的这篇文章

Try James Tauber’s Python Unicode Collation Algorithm. It may not do exactly as you want, but seems well worth a look. For a bit more information about the issues, see this post by Christopher Lenz.


回答 3

您可能也对pyuca感兴趣:

http://jtauber.com/blog/2006/01/27/python_unicode_collat​​ion_algorithm/

尽管肯定不是最精确的方法,但至少可以使它正确一些,这是一种非常简单的方法。由于语言环境不是线程安全的,因此它还会在Web应用程序中击败语言环境,并在整个过程中设置语言设置。它比依赖外部C库的PyICU设置起来容易。

我将脚本上传到github上,因为在撰写本文时原始脚本已关闭,因此我不得不依靠网络缓存来获取它:

https://github.com/href/Python-Unicode-Collat​​ion-Algorithm

我成功地使用此脚本对plone模块中的德语/法语/意大利语文本进行了合理排序。

You might also be interested in pyuca:

http://jtauber.com/blog/2006/01/27/python_unicode_collation_algorithm/

Though it is certainly not the most exact way, it is a very simple way to at least get it somewhat right. It also beats locale in a webapp as locale is not threadsafe and sets the language settings process-wide. It also easier to set up than PyICU which relies on an external C library.

I uploaded the script to github as the original was down at the time of this writing and I had to resort to web caches to get it:

https://github.com/href/Python-Unicode-Collation-Algorithm

I successfully used this script to sanely sort German/French/Italian text in a plone module.


回答 4

摘要和扩展答案:

locale.strcoll在Python 2下,并locale.strxfrm假设您已经安装了有问题的语言环境,实际上可以解决问题,并且表现出色。我也在Windows下进行了测试,这在令人困惑的语言环境名称方面是不同的,但另一方面,默认情况下似乎安装了所有受支持的语言环境。

ICU不一定在实践中会做得更好,但是会做得更多。最值得注意的是,它支持可将不同语言的文本拆分为单词的拆分器。这对于没有单词分隔符的语言非常有用。您需要有一个语料库来用作拆分的基础,因为虽然不包括在内。

它还具有较长的语言环境名称,因此您可以获得语言环境的漂亮显示名称,支持除Gregorian之外的其他日历(尽管我不确定Python接口是否支持该日历),以及成吨的其他或多或少晦涩的语言环境支持。

因此,总而言之:如果您希望按字母顺序和语言环境进行排序,则可以使用该locale模块,除非您有特殊要求,或者还需要更多的语言环境相关功能,例如单词拆分器。

A summary and extended answer:

locale.strcoll under Python 2, and locale.strxfrm will in fact solve the problem, and does a good job, assuming that you have the locale in question installed. I tested it under Windows too, where the locale names confusingly are different, but on the other hand it seems to have all locales that are supported installed by default.

ICU doesn’t necessarily do this better in practice, it however does way more. Most notably it has support for splitters that can split texts in different languages into words. This is very useful for languages that doesn’t have word separators. You’ll need to have a corpus of words to use as a base for the splitting, because that’s not included, though.

It also has long names for the locales so you can get pretty display names for the locale, support for other calendars than Gregorian (although I’m not sure the Python interface supports that) and tons and tons of other more or less obscure locale supports.

So all in all: If you want to sort alphabetically and locale-dependent, you can use the locale module, unless you have special requirements, or also need more locale dependent functionality, like words splitter.


回答 5

我看到答案已经做了出色的工作,只想指出“ 人类排序”中的编码效率低下。要将选择性逐字符转换应用于unicode字符串s,它使用以下代码:

spec_dict = {'Å':'A', 'Ä':'A'}

def spec_order(s):
    return ''.join([spec_dict.get(ch, ch) for ch in s])

Python有一种更好,更快和更简洁的方式来执行此辅助任务(在Unicode字符串上-字节字符串的类似方法具有不同的且不太有用的规范!-):

spec_dict = dict((ord(k), spec_dict[k]) for k in spec_dict)

def spec_order(s):
    return s.translate(spec_dict)

传递给该translate方法的dict将Unicode序号(不是字符串)作为键,这就是为什么我们需要从原始char-to-char进行重建的原因spec_dict。(传递给dict的dict中的值(相对于键,键必须为序数)可以是Unicode序数,任意Unicode字符串,也可以是None来删除相应字符作为翻译的一部分,因此很容易指定“忽略一个某些字符以进行排序”,“将ä映射到ae以进行排序”等)。

在Python 3中,您可以更简单地完成“重建”步骤,例如:

spec_dict = ''.maketrans(spec_dict)

请参阅的文档你可以使用这个其他方式maketrans在Python 3静态方法。

I see the answers have already done an excellent job, just wanted to point out one coding inefficiency in Human Sort. To apply a selective char-by-char translation to a unicode string s, it uses the code:

spec_dict = {'Å':'A', 'Ä':'A'}

def spec_order(s):
    return ''.join([spec_dict.get(ch, ch) for ch in s])

Python has a much better, faster and more concise way to perform this auxiliary task (on Unicode strings — the analogous method for byte strings has a different and somewhat less helpful specification!-):

spec_dict = dict((ord(k), spec_dict[k]) for k in spec_dict)

def spec_order(s):
    return s.translate(spec_dict)

The dict you pass to the translate method has Unicode ordinals (not strings) as keys, which is why we need that rebuilding step from the original char-to-char spec_dict. (Values in the dict you pass to translate [as opposed to keys, which must be ordinals] can be Unicode ordinals, arbitrary Unicode strings, or None to remove the corresponding character as part of the translation, so it’s easy to specify “ignore a certain character for sorting purposes”, “map ä to ae for sorting purposes”, and the like).

In Python 3, you can get the “rebuilding” step more simply, e.g.:

spec_dict = ''.maketrans(spec_dict)

See the docs for other ways you can use this maketrans static method in Python 3.


回答 6


回答 7

最近,我一直在使用zope.ucol(https://pypi.python.org/pypi/zope.ucol)执行此任务。例如,对德语ß进行排序:

>>> import zope.ucol
>>> collator = zope.ucol.Collator("de-de")
>>> mylist = [u"a", u'x', u'\u00DF']
>>> print mylist
[u'a', u'x', u'\xdf']
>>> print sorted(mylist, key=collator.key)
[u'a', u'\xdf', u'x']

zope.ucol还包装ICU,因此可以替代PyICU。

Lately I’ve been using zope.ucol (https://pypi.python.org/pypi/zope.ucol) for this task. For example, sorting the german ß:

>>> import zope.ucol
>>> collator = zope.ucol.Collator("de-de")
>>> mylist = [u"a", u'x', u'\u00DF']
>>> print mylist
[u'a', u'x', u'\xdf']
>>> print sorted(mylist, key=collator.key)
[u'a', u'\xdf', u'x']

zope.ucol also wraps ICU, so would be an alternative to PyICU.


回答 8

完整的UCA解决方案

执行此操作的最简单,最简单,最直接的方法是对Perl库模块Unicode :: Collat​​e :: Locale进行调出,它是标准Unicode :: Collat​​e模块的子类。您需要做的就是将"xv"瑞典的语言环境值传递给构造函数。

(对于瑞典语文本,您可能不一定会对此有所了解,但是由于Perl使用抽象字符,因此您可以使用任何Unicode代码点-无论是平台还是构建方式!很少有语言提供这种便利。我提到它是因为我一直在与最近在这个令人发指的问题上与Java失去了很多战斗。)

问题是,我不知道如何从Python访问Perl模块-除了通过使用shell标注或两侧管道之外。因此,为此,我为您提供了一个完整的工作脚本ucsort,您可以调用它来轻松轻松地完成您所要求的。

该脚本100%兼容完整的Unicode排序算法,并支持所有定制选项!而且,如果您安装了可选模块或运行Perl 5.13或更高版本,则可以完全访问易于使用的CLDR语言环境。见下文。

示范

想象一下这样设置的输入集:

b o i j n l m å y e v s k h d f g t ö r x p z a ä c u q

默认的按代码点排序将生成:

a b c d e f g h i j k l m n o p q r s t u v x y z ä å ö

这在每个人的书中都是不正确的。使用我的使用Unicode归类算法的脚本,您将获得以下命令:

% perl ucsort /tmp/swedish_alphabet | fmt
a å ä b c d e f g h i j k l m n o ö p q r s t u v x y z

这是默认的UCA排序。要获取瑞典语言环境,请以下方式调用ucsort

% perl ucsort --locale=sv /tmp/swedish_alphabet | fmt
a b c d e f g h i j k l m n o p q r s t u v x y z å ä ö

这是一个更好的输入演示。首先,输入集:

% fmt /tmp/swedish_set
cTD cDD Cöd Cbd cAD cCD cYD Cud cZD Cod cBD Cnd cQD cFD Ced Cfd cOD
cLD cXD Cid Cpd cID Cgd cVD cMD cÅD cGD Cqd Cäd cJD Cdd Ckd cÖD cÄD
Ctd Czd Cxd cHD cND cKD Cvd Chd Cyd cUD Cld Cmd cED Crd Cad Cåd Ccd
cRD cSD Csd Cjd cPD

按代码点,排序方式如下:

Cad Cbd Ccd Cdd Ced Cfd Cgd Chd Cid Cjd Ckd Cld Cmd Cnd Cod Cpd Cqd
Crd Csd Ctd Cud Cvd Cxd Cyd Czd Cäd Cåd Cöd cAD cBD cCD cDD cED cFD
cGD cHD cID cJD cKD cLD cMD cND cOD cPD cQD cRD cSD cTD cUD cVD cXD
cYD cZD cÄD cÅD cÖD

但是使用默认的UCA可以使这种方式排序:

% ucsort /tmp/swedish_set | fmt
cAD Cad cÅD Cåd cÄD Cäd cBD Cbd cCD Ccd cDD Cdd cED Ced cFD Cfd cGD
Cgd cHD Chd cID Cid cJD Cjd cKD Ckd cLD Cld cMD Cmd cND Cnd cOD Cod
cÖD Cöd cPD Cpd cQD Cqd cRD Crd cSD Csd cTD Ctd cUD Cud cVD Cvd cXD
Cxd cYD Cyd cZD Czd

但是在瑞典语言环境中,这种方式是:

% ucsort --locale=sv /tmp/swedish_set | fmt
cAD Cad cBD Cbd cCD Ccd cDD Cdd cED Ced cFD Cfd cGD Cgd cHD Chd cID
Cid cJD Cjd cKD Ckd cLD Cld cMD Cmd cND Cnd cOD Cod cPD Cpd cQD Cqd
cRD Crd cSD Csd cTD Ctd cUD Cud cVD Cvd cXD Cxd cYD Cyd cZD Czd cÅD
Cåd cÄD Cäd cÖD Cöd

如果您希望大写字母在小写字母之前排序,请执行以下操作:

% ucsort --upper-before-lower --locale=sv /tmp/swedish_set | fmt
Cad cAD Cbd cBD Ccd cCD Cdd cDD Ced cED Cfd cFD Cgd cGD Chd cHD Cid
cID Cjd cJD Ckd cKD Cld cLD Cmd cMD Cnd cND Cod cOD Cpd cPD Cqd cQD
Crd cRD Csd cSD Ctd cTD Cud cUD Cvd cVD Cxd cXD Cyd cYD Czd cZD Cåd
cÅD Cäd cÄD Cöd cÖD

定制排序

您可以使用ucsort做许多其他事情。例如,以下是英文标题的排序方法:

% ucsort --preprocess='s/^(an?|the)\s+//i' /tmp/titles
Anathem
The Book of Skulls
A Civil Campaign
The Claw of the Conciliator
The Demolished Man
Dune
An Early Dawn
The Faded Sun: Kesrith
The Fall of Hyperion
A Feast for Crows
Flowers for Algernon
The Forbidden Tower
Foundation and Empire
Foundations Edge
The Goblin Reservation
The High Crusade
Jack of Shadows
The Man in the High Castle
The Ringworld Engineers
The Robots of Dawn
A Storm of Swords
Stranger in a Strange Land
There Will Be Time
The White Dragon

通常,您将需要Perl 5.10.1或更高版本才能运行脚本。为了支持语言环境,您必须安装可选的CPAN模块Unicode::Collate::Locale。或者,您可以安装Perl 5.13+的开发版本,该版本标准包含该模块。

调用约定

这是一个快速的原型,因此ucsort大多没有记录。但这是它在命令行上接受的开关/选项的摘要:

    # standard options
    --help|?
    --man|m
    --debug|d

    # collator constructor options
    --backwards-levels=i
    --collation-level|level|l=i
    --katakana-before-hiragana
    --normalization|n=s
    --override-CJK=s
    --override-Hangul=s
    --preprocess|P=s
    --upper-before-lower|u
    --variable=s

    # program specific options
    --case-insensitive|insensitive|i
    --input-encoding|e=s
    --locale|L=s
    --paragraph|p
    --reverse-fields|last
    --reverse-output|r
    --right-to-left|reverse-input

是的,好的:那确实是我调用时使用的参数列表Getopt::Long,但是您明白了。:)

如果您可以弄清楚如何直接从Python调用Perl库模块而不调用Perl脚本,则一定要这样做。我只是不知道自己。我很想学习如何。

同时,我相信此脚本将完成您需要做的所有工作,甚至更多! 现在,我将其用于所有文本排序。它最后确实已经需要很长一段时间我。

唯一的缺点是,这种--locale说法会导致性能下降,尽管它对于常规,非语言环境但仍100%符合UCA的排序足够快。由于它将所有内容加载到内存中,因此您可能不想在千兆字节的文档上使用它。我每天使用它很多次,并且可以确保最后一次理智的文本排序非常好。

A Complete UCA Solution

The simplest, easiest, and most straightforward way to do this it to make a callout to the Perl library module, Unicode::Collate::Locale, which is a subclass of the standard Unicode::Collate module. All you need do is pass the constructor a locale value of "xv" for Sweden.

(You may not neccesarily appreciate this for Swedish text, but because Perl uses abstract characters, you can use any Unicode code point you please — no matter the platform or build! Few languages offer such convenience. I mention it because I’ve fighting a losing battle with Java a lot over this maddening problem lately.)

The problem is that I do not know how to access a Perl module from Python — apart, that is, from using a shell callout or two-sided pipe. To that end, I have therefore provided you with a complete working script called ucsort that you can call to do exactly what you have asked for with perfect ease.

This script is 100% compliant with the full Unicode Collation Algorithm, with all tailoring options supported!! And if you have an optional module installed or run Perl 5.13 or better, then you have full access to easy-to-use CLDR locales. See below.

Demonstration

Imagine an input set ordered this way:

b o i j n l m å y e v s k h d f g t ö r x p z a ä c u q

A default sort by code point yields:

a b c d e f g h i j k l m n o p q r s t u v x y z ä å ö

which is incorrect by everybody’s book. Using my script, which uses the Unicode Collation Algorithm, you get this order:

% perl ucsort /tmp/swedish_alphabet | fmt
a å ä b c d e f g h i j k l m n o ö p q r s t u v x y z

That is the default UCA sort. To get the Swedish locale, call ucsort this way:

% perl ucsort --locale=sv /tmp/swedish_alphabet | fmt
a b c d e f g h i j k l m n o p q r s t u v x y z å ä ö

Here is a better input demo. First, the input set:

% fmt /tmp/swedish_set
cTD cDD Cöd Cbd cAD cCD cYD Cud cZD Cod cBD Cnd cQD cFD Ced Cfd cOD
cLD cXD Cid Cpd cID Cgd cVD cMD cÅD cGD Cqd Cäd cJD Cdd Ckd cÖD cÄD
Ctd Czd Cxd cHD cND cKD Cvd Chd Cyd cUD Cld Cmd cED Crd Cad Cåd Ccd
cRD cSD Csd Cjd cPD

By code point, that sorts this way:

Cad Cbd Ccd Cdd Ced Cfd Cgd Chd Cid Cjd Ckd Cld Cmd Cnd Cod Cpd Cqd
Crd Csd Ctd Cud Cvd Cxd Cyd Czd Cäd Cåd Cöd cAD cBD cCD cDD cED cFD
cGD cHD cID cJD cKD cLD cMD cND cOD cPD cQD cRD cSD cTD cUD cVD cXD
cYD cZD cÄD cÅD cÖD

But using the default UCA makes it sort this way:

% ucsort /tmp/swedish_set | fmt
cAD Cad cÅD Cåd cÄD Cäd cBD Cbd cCD Ccd cDD Cdd cED Ced cFD Cfd cGD
Cgd cHD Chd cID Cid cJD Cjd cKD Ckd cLD Cld cMD Cmd cND Cnd cOD Cod
cÖD Cöd cPD Cpd cQD Cqd cRD Crd cSD Csd cTD Ctd cUD Cud cVD Cvd cXD
Cxd cYD Cyd cZD Czd

But in the Swedish locale, this way:

% ucsort --locale=sv /tmp/swedish_set | fmt
cAD Cad cBD Cbd cCD Ccd cDD Cdd cED Ced cFD Cfd cGD Cgd cHD Chd cID
Cid cJD Cjd cKD Ckd cLD Cld cMD Cmd cND Cnd cOD Cod cPD Cpd cQD Cqd
cRD Crd cSD Csd cTD Ctd cUD Cud cVD Cvd cXD Cxd cYD Cyd cZD Czd cÅD
Cåd cÄD Cäd cÖD Cöd

If you prefer uppercase to sort before lowercase, do this:

% ucsort --upper-before-lower --locale=sv /tmp/swedish_set | fmt
Cad cAD Cbd cBD Ccd cCD Cdd cDD Ced cED Cfd cFD Cgd cGD Chd cHD Cid
cID Cjd cJD Ckd cKD Cld cLD Cmd cMD Cnd cND Cod cOD Cpd cPD Cqd cQD
Crd cRD Csd cSD Ctd cTD Cud cUD Cvd cVD Cxd cXD Cyd cYD Czd cZD Cåd
cÅD Cäd cÄD Cöd cÖD

Customized Sorts

You can do many other things with ucsort. For example, here is how to sort titles in English:

% ucsort --preprocess='s/^(an?|the)\s+//i' /tmp/titles
Anathem
The Book of Skulls
A Civil Campaign
The Claw of the Conciliator
The Demolished Man
Dune
An Early Dawn
The Faded Sun: Kesrith
The Fall of Hyperion
A Feast for Crows
Flowers for Algernon
The Forbidden Tower
Foundation and Empire
Foundation’s Edge
The Goblin Reservation
The High Crusade
Jack of Shadows
The Man in the High Castle
The Ringworld Engineers
The Robots of Dawn
A Storm of Swords
Stranger in a Strange Land
There Will Be Time
The White Dragon

You will need Perl 5.10.1 or better to run the script in general. For locale support, you must either install the optional CPAN module Unicode::Collate::Locale. Alternately, you can install a development versions of Perl, 5.13+, which include that module standardly.

Calling Conventions

This is a rapid prototype, so ucsort is mostly un(der)documented. But this is its SYNOPSIS of what switches/options it accepts on the command line:

    # standard options
    --help|?
    --man|m
    --debug|d

    # collator constructor options
    --backwards-levels=i
    --collation-level|level|l=i
    --katakana-before-hiragana
    --normalization|n=s
    --override-CJK=s
    --override-Hangul=s
    --preprocess|P=s
    --upper-before-lower|u
    --variable=s

    # program specific options
    --case-insensitive|insensitive|i
    --input-encoding|e=s
    --locale|L=s
    --paragraph|p
    --reverse-fields|last
    --reverse-output|r
    --right-to-left|reverse-input

Yeah, ok: that’s really the argument list I use for the call to Getopt::Long, but you get the idea. :)

If you can figure out how to call Perl library modules from Python directly without calling a Perl script, by all means do so. I just don’t know how myself. I’d love to learn how.

In the meantime, I believe this script will do what you need done in all its particular — and more! I now use this for all of text sorting. It finally does what I’ve needed for a long, long time.

The only downside is that --locale argument causes performance to go down the tubes, although it’s plenty fast enough for regular, non-locale but still 100% UCA compliant sorting. Since it loads everything in memory, you probably don’t want to use this on gigabyte documents. I use it many times a day, and it sure it great having sane text sorting at last.


回答 9

这是远从你的使用情况的完整解决方案,但你可以看看的unaccent.py从effbot.org脚本。它的主要作用是删除文本中的所有重音。您可以使用“经过消毒的”文本按字母顺序排序。(有关详细说明,请参阅页面。)

It is far from a complete solution for your use case, but you could take a look at the unaccent.py script from effbot.org. What it basically does is remove all accents from a text. You can use that ‘sanitized’ text to sort alphabetically. (For a better description see this page.)


回答 10

杰夫阿特伍德(Jeff Atwood)在“ 自然排序顺序”上写了一篇不错的文章,他链接到一个脚本,该脚本几乎可以完成您的要求

无论如何,它都不是琐碎的脚本,但是可以解决问题。

Jeff Atwood wrote a good post on Natural Sort Order, in it he linked to a script which does pretty much what you ask.

It’s not a trivial script, by any means, but it does the trick.