Re: Reversing Arabic String direction
by LanX (Saint) on Jul 10, 2014 at 21:49 UTC
|
I think it can be done more elegantly, but this works for me
DB<112> $str ="a123bc45de"
=> "a123bc45de"
DB<113> join "", reverse map { /\d/ ? $_ : scalar reverse $_ } split
+ /(\d+)/, $str
=> "ed45cb123a"
HTH! :)
edit
- The split breaks the string into a list of digit and non digit substrings.
- The map does a reverse string (scalar context) on non-digits only
- The join concats the reversed list (list context!) again to a string
Cheers Rolf
(addicted to the Perl Programming Language)
| [reply] [d/l] |
|
| [reply] |
|
nope IMHO thats the way it should be in Arabic, if numbers were reversed:
DB<115> join "", reverse map { /\d/ ? $_ : scalar reverse $_ } split
+ /(\d+)/, name_21
=> "21_eman"
But I didn't check your code...
Cheers Rolf
(addicted to the Perl Programming Language)
| [reply] [d/l] |
|
|
Re: Reversing Arabic String direction
by Jim (Curate) on Jul 11, 2014 at 03:55 UTC
|
Is this a situation that requires the application of the Unicode bidi algorithm? If it is, then perhaps the CPAN module Text::Bidi may be useful to you.
What software are you using to determine that the Arabic characters aren't displayed in the proper direction? Maybe the problem is with this software, not the Arabic text itself.
See Visual vs. logical ordering of text.
| [reply] |
Re: Reversing Arabic String direction
by boftx (Deacon) on Jul 10, 2014 at 21:46 UTC
|
Here is a very crude, brute-force approach. I've no doubt that one of the regex masters here can do it much more efficiently.
use strict;
use warnings;
# I have no idea how unicode might affect this
my $wrongway = 'This is a string with numbers 12345 that must be rever
+sed without reversing the numbers.';
my @tmp;
my @raw = split('',$wrongway);
my @numeric;
my $was_numeric = 0;
for ( @raw ) {
if ( /\d/ ) {
push( @numeric, $_ );
$was_numeric = 1;
next;
}
elsif ( $was_numeric ) {
unshift( @tmp, @numeric );
$was_numeric = 0;
@numeric = ();
}
unshift( @tmp, $_ );
}
my $right_way =join('', @tmp);
print "$wrongway\n";
print $right_way;
print "\n\n";
Again, this is very ugly but might point the way to how to approach the problem.
You must always remember that the primary goal is to drain the swamp even when you are hip-deep in alligators.
| [reply] [d/l] |
Re: Reversing Arabic String direction
by AppleFritter (Vicar) on Jul 10, 2014 at 21:51 UTC
|
Without knowing anything at all about Arabic script... off the top of my head, I'd suggest splitting your string into chunks along letter/digit boundaries, reversing not reversing each chunk as appropriate, and then putting the chunks together again in the right order. | [reply] |
Re: Reversing Arabic String direction
by Anonymous Monk on Jul 10, 2014 at 22:13 UTC
|
Well, it's hard to tell what to do without knowing any Arabic. Try this:
use utf8;
use open qw(:encode(utf-8) :std);
...
$arabic_string =~ s/(\p{L}+)/reverse $1/eg;
You should've posted some examples. Then again, Perlmonks likes to mangle non-ASCII symbols. | [reply] [d/l] |
|
building on this, you'll need a second reverse and substitute numbers only
DB<136> $str ="a123bc45de"
=> "a123bc45de"
DB<137> $str2= reverse $str
=> "ed54cb321a"
DB<138> $str2 =~ s/(\p{N}+)/reverse $1/ge
=> 2
DB<139> $str2
=> "ed45cb123a"
\p{N} is a guess, I'll check now¹! :)
update
changed order of inversion to make it clearer.
Cheers Rolf
(addicted to the Perl Programming Language)
¹) perlre only mentions \p{Digit} and \p{isDigit} ... both work for me. | [reply] [d/l] [select] |
|
| [reply] |
|
(should be)
use open qw(:encoding(utf-8) :std);
| [reply] [d/l] |
|
Actually, it appears you want to reverse the whole string, rather then word-by-word. Then it wouldn't work.
| [reply] |
Re: Reversing Arabic String direction
by BillKSmith (Monsignor) on Jul 11, 2014 at 17:29 UTC
|
Combine regex with reverse.
use strict;
use warnings;
my $string = '21eman 21_eman';
print scalar reverse($string =~ s/(\d+)/reverse $1/egr);
OUTPUT:
name_21 name21
| [reply] [d/l] [select] |