使用perl或python将阿拉伯字符“ا”替换为一个单词中的“a”,但将“ә”替换为另一个单词

时间:2013-01-30 10:05:17

标签: python regex perl arabic

我需要将纯文本UTF8文档从R语言更改为L语言为拉丁语言。不幸的是,它并不像角色字符音译那么容易 例如,R到L语言(ا)中的“a”可以是“a”或“ә”,具体取决于单词构成。

用g,k,e或hamza(گ,ك,ە,ء)的词语
我需要将所有a,o,i,u(,,و,ى,ۇ)改为拉丁语ә,ѳ,i,ü(称为“软”元音)。
例如。 سالەم成为sәlêm,ءۇي成为üy,سوزمەن成为sѳzmên

在没有g,k,e或hamza(گ,ك,ە,ء)的词汇中 a,o,i,u改为拉丁字符a,o,i,u(称为“硬”元音)。
例如。 الما成为alma,becomesۇ变成ul,ورتا变成orta。

实质上,
g,k,e或hamza是阿拉伯文字中的发音指南 在拉丁语中,我需要两组不同的元音,具体取决于阿拉伯语中的原始单词。

我在想我可能需要在第一步中使用“软”元音词,然后在文档的其余部分单独执行查找和替换。但是,如何使用perl或python进行这样的查找和替换?

这是一个unicode示例:\ U + 0633 \ U + 0627 \ U + 0644 \ U + 06D5 \ U + 0645 \ U + 0648 \ U + 0631 \ U + 062A \ U + 0627 \ U + 0674 \ U + 06C7 \ U + 064A \ U + 0633 \ U + 0648 \ U + 0632 \ U + 0645 \ U + 06D5 \ U + 0645 \ U + 0627 \ U + 0644 \ U + 0645 \ U + 0627 \ U + 06C7 \ U + 0644 \ U + 0645 \ U + 06D5 \ U + 0646 \ U + 0649 \ U + 06AD \ U + 0627 \ U + 062A \ U + 0649 \ U + 0645 \ U + 0634 \ U + 0627 \ U + 0644 \ U + 0642 \ U + 0627 \ U + 0631。

它应该看起来像:“sәlêmortaüysѳzmênalmaulmêningatenxalқar”。(注意:字母ڭ,即U + 06AD实际上最终为两个字母,n + g,以制作“ - “声音”。它看起来不应该像“salêmortauysozmênalmaulmêningatimalқar”,也不应该像“sәlêmѳrtәüysѳzmênәlmәülmêningәtimxәlқәr”。

非常感谢任何帮助。

4 个答案:

答案 0 :(得分:4)

您可以使用序数映射构建自己的转换表来替换字符,对于每组字符,您需要一个单独的表(对于元音)。这只是一个局部的例子,但应该让你知道如何做到这一点。


注意您需要为其他字符指定转换表。如果需要,您还可以将一个阿拉伯字符翻译成多个拉丁字母。如果将输出与请求进行比较,则转换表中的所有字符似乎都匹配正确。

import re

s1 = {u'ء',u'ە',u'ك',u'گ'} # g, k, e, hamza

t1 = {ord(u'ا'):u'ә',  # first case
      ord(u'و'):u'ѳ',
      ord(u'ى'):u'i',
      ord(u'ۇ'):u'ü',
      ord(u'ڭ'):u'ng'} # with double

t2 = {ord(u'ا'):u'a',  # second case
      ord(u'و'):u'o',
      ord(u'ى'):u'i',
      ord(u'ۇ'):u'u',
      ord(u'ڭ'):u'ng'} # with double

def subst(word):    
    if any(c in s1 for c in word):
        return word.translate(t1)
    else:
        return word.translate(t2)

s = u'سالەم ورتا ءۇي سوزمەن الما ۇل مەنىڭ اتىم شالقار'

print re.sub(ur'(\S+)', lambda m: subst(m.group(1)), s)

# output:    سәلەم oرتa ءüي سѳزمەن aلمa uل مەنing aتiم شaلقaر

# requested: sәlêm orta üy sѳzmên alma ul mêning atim xalқar

答案 1 :(得分:4)

命令:

$ echo سالەم ورتا ءۇي سوزمەن الما ۇل مەنىڭ اتىم شالقار | ./arabic-to-latin

输出:

sәlêm orta üy sѳzmên alma ul mêning atim xalқar

使用文件而不是stdin / stdout:

$ ./arabic-to-latin input_file_with_arabic_text_in_utf8 >output_latin_in_utf8

arabic-to-latin档案:

#!/usr/bin/perl
use strict;
use warnings;
use utf8;
use open qw(:std :utf8);
#XXX normalization

sub replace_word {
    my ($word) = @_;
    $_ = $word;
    if (/ء|ە|ك|گ/) { # g, k, e, or hamza in the word
        tr/اوىۇ/әѳiü/; # soft
    } else {
        tr/اوىۇ/aoiu/; # hard
    }
    tr/سلەمرتزنشق/slêmrtznxқ/;
    s/ءüي/üy/g;
    s/ڭ/ng/g;
    $_;
}

while (my $line = <>) {
    $line =~ s/(\w+)/replace_word($1)/ge;
    print $line;
}

使arabic-to-latin文件可执行:

$ chmod +x ./arabic-to-latin

答案 2 :(得分:0)

我不会说perl或python(或者阿拉伯语),但这是你可以使用的基本思想(使用Javascript,但应该可以翻译成任何替换为回调的语言):

//replace [a-z] with the proper unicode range for arabic
input.replace(/[a-z]+/, function(word){
  //replace `[gkeh]` with their arabic equivalents
  if(/[gkeh]/.test(word){
    return word.replace(/./, function(c){
      return withSoftVowels[c]
    })
  }else{
    return word.replace(/./, function(c){
      return withHardVowels[c]
    })
  }
})

即,将输入拆分为单词,然后根据该单词是否包含特定字符,使用两个转换表中的一个替换该单词中的每个符号。正则表达式可用于两者,或者您可以按字边界分割并在单词内进行替换(同时使用等效的indexOf进行分支)。

这是没有回调的方法(如果Javascript中的字符串是可变的):

var words = input.split(' ');
var table;
for(var i=0; i<words.length; i++){
  if(words[i].test([gkeh]){
    table = softTable;
  }else{
    table = hardTable;
  }
  for(var j=0; j<words[i].length; j++){
    if(words[i][j] in table){
      words[i][j]=table[words[i][j]];
    }
  }
}
return words.join(' ');

答案 3 :(得分:0)

这个python代码基于Jan Dvorak的代码,应该提供一个起点:

import re
import codecs

def replace_word(word):
    if re.search(ur'[gkeh]', word):
        # hard vowels
        word = word.replace(u'a', u'ә')
        word = word.replace(u'o', u'ѳ')
        word = word.replace(u'i', u'i')
        word = word.replace(u'u', u'ü')
    else:
        # soft vowels
        word = word.replace(u'a', u'a')
        word = word.replace(u'o', u'o')
        word = word.replace(u'i', u'i')
        word = word.replace(u'u', u'u')
    return word

with codecs.open('input.txt', 'w', 'utf-8') as fh:
    input = fh.read()

output = re.sub(ur'(\S+)', lambda m: replace_word(m.group(1)), input)

with codecs.open('output.txt', 'w', 'utf-8') as fh:
    fh.write(output)