如何按字母数字字符串中的数字排序? [英] How to sort by numbers in alpha numeric string?
问题描述
如果我使用以下格式的字符串数组:
[1900] ABC 15
如何使用perl sort
对数组进行排序,以便按第一个数字排序,然后按第二个数字排序?
此示例来自 perldoc排序似乎是相关的:
my @new = sort {
($b =~ /=(\d+)/)[0] <=> ($a =~ /=(\d+)/)[0]
||
fc($a) cmp fc($b)
} @old;
从文档中提取的示例显示了这一想法:按一个条件进行比较,以及如果通过cmp
或<=>
发现它们相等,则 Schwartzian变换.>
但是请记住,此类优化仅在较大的数据集上可证明,对于简单计算而言,其开销也是如此.
上面的基本sort
通常就足够了.
根据要求讨论了问题" using perl sort
",我想补充一下,还有一些专门为此目的编写的模块,即自然排序",因为它们叫它.
use warnings;
use strict;
use feature 'say';
use Sort::Key::Natural qw(natsort);
my @strings = qw(
19_b_2
13_z_7
13_b_7
20_a_1
13_b_5
);
say for natsort @strings;
打印
13_b_5 13_b_7 13_z_7 19_b_2 20_a_1
这首先对数字部分进行排序,然后对字母进行排序.不需要第二种,上面的sort
也不做.但是该手动排序很容易用标准进行修改,而好的模块当然不能灵活(不能删除字母排序).
注意 [0-9]
与\d
匹配,但是其他字符(我被告知多了360个字符)也可以识别Unicode.从5.14开始可用的/a
字符集修饰符并非如此.但这具有比仅限制\d
更广泛的作用.在 perlre 中搜索/a
.
因此,在这里我将0-9
用于精度和少量效率,而没有限制\s
,\w
和POSIX字符类.
If I have an array of strings with the following format:
[1900] ABC 15
How can I sort the array using perl sort
so that it sorts by the first number, then by the second?
This example from perldoc sort seems to be relevant:
my @new = sort {
($b =~ /=(\d+)/)[0] <=> ($a =~ /=(\d+)/)[0]
||
fc($a) cmp fc($b)
} @old;
The example pulled from docs shows the idea: Compare by one criterion and if they are found equal by the cmp
or <=>
equality operators, which then return 0
, go to the next criterion.
So in this case compare by the first number in the string, then by the second.
use warnings;
use strict;
use feature 'say';
my @old = ('[1900] ABC 15', '[1900] ABC 5', '[1800] ABC 20');
my @new = sort {
my ($a1, $a2) = $a =~ /([0-9]+)/g;
my ($b1, $b2) = $b =~ /([0-9]+)/g;
$a1 <=> $b1 or $a2 <=> $b2;
} @old;
say for @new;
prints
[1800] ABC 20 [1900] ABC 5 [1900] ABC 15
If the sort needs to be in the descending order swap a
and b
in comparisons.
This can be done more efficiently, in the first place by pre-computing the regexes for the whole list so that they aren't re-done every time an element is compared. The continuation of the example from docs shows this, the last version being the Schwartzian transform.
But recall that such optimizations are demonstrable only for larger data sets, and that for simple calculations their overhead counts, too.
The above basic sort
generally suffices.
Having discussed the problem "using perl sort
", as asked for, I'd like to add that there are also modules written precisely for this purpose, "natural sorting," as they call it.
An example with Sort::Key::Natural
use warnings;
use strict;
use feature 'say';
use Sort::Key::Natural qw(natsort);
my @strings = qw(
19_b_2
13_z_7
13_b_7
20_a_1
13_b_5
);
say for natsort @strings;
Prints
13_b_5 13_b_7 13_z_7 19_b_2 20_a_1
This sorts on numerical parts first, and then alphabetically. That second sort wasn't asked for and the sort
above doesn't do it. But that manual sort can easily be amended with criterion while the nice module of course can't be as flexible (can't drop the alphabetical sort).
Note A [0-9]
is matched by \d
but so are other characters (360 more I'm told), it being Unicode aware. This isn't the case with /a
character set modifier, available since 5.14. But that has an effect broader than restricting just \d
. Search for /a
in perlre.
Thus here I used 0-9
for precision and a small measure of efficiency, and without restricting \s
, \w
and POSIX character classes.
这篇关于如何按字母数字字符串中的数字排序?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!