Question: Is there a way that I can sort an array based on a sub-string of the array element. For example, lets say I have the following array:

```
@myArray = qw("AAA|111|bbb" "CCC|333|ddd" "EEE|444|fff" "GGG|222|hhh");

```

I want to sort this array based on the sub-string starting at position 4 (zero-based) for a length of 3 (in the first array element in my example, that would be "111").

The length of each array element will always be the same for all elements and the sub-string I want to sort on will always be in the same position for the same length in the array element.

This is what my sorted output would look like:

```
AAA|111|bbb

GGG|222|hhh

CCC|333|ddd

EEE|444|fff

```

Also, while I am showing numbers as the sub-string in my example, it could be non-number values in there too. So the sort would have to work for non-numbers too.

Answer: 
[sort](https://perldoc.pl/functions/sort) can take the first parameter that is a code block that compares two elements:

```
#!/usr/bin/perl
use warnings;
use strict;
use feature qw{ say };

my @myArray = qw( AAA|111|bbb CCC|333|ddd EEE|444|fff GGG|222|hhh );

say for sort { substr($a, 4, 3) cmp substr($b, 4, 3) } @myArray;

```

See also [substr](http://p3rl.org/substr).

Note that I removed the double quotes from the `qw()`. "qw" stands for "quote words", so no quotes are needed (in fact, they would be part of the strings which isn't what you wanted).

Using the [Sort::Key](http://p3rl.org/Sort::Key) module, it can get even simpler:

```
use Sort::Key qw{ keysort };
...
say for keysort { substr $_, 4, 3 } @myArray;

```
What's the use of pipes if this is a record of fixed-length fields?

If you were to treat the input as pipe-separated values, then your code would become

```
say for sort { ( split /\|/, $a )[1] <=> ( split /\|/, $b )[1] } @myArray;

```

and

```
use Sort::Key qw( ikeysort );

say for ikeysort { ( split /\|/ )[1] } @myArray;

```

[*This is not meant to be a complete answer, but an extension of choroba's.*]