Como pesquisar uma palavra árabe no texto sem seus sinais / diacríticos?


11

Em árabe, como em alguns outros idiomas, existe o que é chamado de diacríticos para aprimorar a pronúncia. Não há convenção sobre quantos diacríticos devem ser escritos para uma única palavra. Alguns usam o mínimo (que eu prefiro) apenas o suficiente para desambiguar a pronúncia, enquanto outros os usam de forma supérflua ou apenas para fins caligráficos estéticos. Assim, há uma grande variação sobre o que e quantos diacríticos estão associados a uma palavra. Quando isearch-forward/backwardpressiono C-s/r, surge um problema quando o digito no mini-buffer de pesquisa sem diacríticos. Ele não corresponderá à mesma palavra no texto se tiver diacríticos, tornando a tarefa de procurar essa palavra com seus potenciais diacríticos sempre insatisfatórios.

Existe uma maneira de fazer a pesquisa / regexp desconhecer os diacríticos? Espero que haja uma resposta que possa ser estendida para incluir regexp C-M-s/re greppesquisar que eu uso com frequência no helm-projectile para procurar uma palavra em projetos de látex com vários arquivos.

Atualização
Seria bom ver que o Emacs, em todas as suas funções de pesquisa, executa a etapa de remoção do texto (de acentos / diacríticos / o nome dele) antes de corresponder a etapa como um comportamento padrão que pode ser desativado por um prefixo sob demanda não importa qual idioma esteja disponível. Normalmente, quando procuro algo que não espero do melhor editor (Emacs) falhar nessa tarefa, apenas por causa de alguns sinais diacríticos ou sotaques que raramente são necessários para realizar tarefas de texto mundanas.


1
Veja as ucs-normalize-*funções em lisp/international/ucs-normalize.el. Não há dobramento de pesquisa predefinido para eles, como ocorre com o dobramento de maiúsculas e minúsculas, mas você pode pelo menos normalizar uma região antes de pesquisá-la. Uma boa implementação é provavelmente uma tarefa bastante complexa.
Ted Zlatanov


@Nome, o árabe tem muito mais possibilidades de combinações de letras (26) com acentos / diacríticos, portanto não é para o árabe. Parece que não há substituto para bibliotecas específicas de idioma. Não acredito que isso já foi implementado no Microsoft Word e não no Emacs todos esses anos atrás.
doctorado

1
O árabe tem cerca de 80 diacríticos e 26 letras, tornando todas as combinações uma tarefa assustadora. Deve haver alguma maneira de retirar o texto de seus sinais diacríticos, como o phpimplementado: stackoverflow.com/a/25563250/1288722 - também implementado em Javascript: stackoverflow.com/a/7193622/1288722
doutorado

Pensamento: não é possível executar a string através dessa função de limpeza php e passar o resultado para algo semelhante a helm-swoop?
Sean Allred

Respostas:


5

Aqui está um começo difícil, com base na lista de caracteres combinados nesta resposta (e depois estendida). (Marcando isso como wiki da comunidade - edite e melhore isso!)

(defconst arabic-diacritics '(#x064b #x064c #x064d #x064e #x064f #x0650 #x0651 #x0652 #x0653 #x0654 #x0655 #x0670)
  "Unicode codepoints for Arabic combining characters.")
(defconst arabic-diacritics-regexp (regexp-opt (mapcar #'string arabic-diacritics)))

(defconst arabic-equivalents
  '(
    ;; "alef" is equivalent to "alef with hamza above" etc
    (#x0627 #x0623 #x0625 #x0622)))

;; (require 'cl-lib)    
;; (defun arabic-strip-diacritics (string)
;;   (cl-reduce (lambda (s c) (remove c s)) arabic-diacritics :initial-value string))

(defun arabic-search-without-diacritics (string)
  (interactive (list (read-string "Search for: " nil nil nil t)))
  (let ((regexp
         (apply #'concat
                (mapcar (lambda (c)
                          (let ((equivalents (assq c arabic-equivalents)))
                            (concat
                             (if equivalents
                                 (regexp-opt (mapcar #'string equivalents))
                               (regexp-quote (string c)))
                             arabic-diacritics-regexp "*")))
                        string))))
    (search-forward-regexp regexp)))

Portanto, se um buffer contiver "الْحَمْدُ لِلَّهِ رَبِّ الْعَالَمِينَ", e eu avalio (arabic-search-without-diacritics "الحمد لله رب العالمين"), ele encontra o texto. Também funciona de forma interativa, como M-x arabic-search-without-diacritics.

Abordagem alternativa:

Aqui está um exemplo de código completo que demonstra como marcas diacríticas e outras marcas não espaçadoras ( Mnpropriedade) podem ser removidas de seqüências normalizadas em correspondências regexp. Ele trabalha com os exemplos dados e a IMO é a abordagem correta.

(defun kill-marks (string)
  (concat (loop for c across string
                when (not (eq 'Mn (get-char-code-property c 'general-category)))
                collect c)))

(let* ((original1 "your Arabic string here")
      (normalized1 (ucs-normalize-NFKD-string original1))
      (original2 "your other Arabic string here")
      (normalized2 (ucs-normalize-NFKD-string original2)))
  (equal
   (replace-regexp-in-string "." 'kill-marks normalized1)
   (replace-regexp-in-string "." 'kill-marks normalized2)))

Adicionei mais dois diacríticos comumente usados ​​em árabe à sua bela lista. Esta é a lista completa de classificados 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1648- taxa gratuita para atualização.
doctorado

A primeira função arabic-search-without-diacriticsfunciona bem, mas quebra com algumas palavras, não sei por que, como esta الأَ. Outra ressalva: eu sempre tenho que definir o método de entrada como árabe quando insiro minha string no mini-buffer, enquanto na isearch-forward/backwardfunção ela permanece lá.
doctorado

kill-marksé a melhor abordagem para fornecer texto sem complicações pronto para todos os tipos de pesquisa. O que não está claro para mim é como implementar isso em um buffer inteiro e depois em vários arquivos?
doctorado

1
Obrigado! é possível isearch-forward/backwardrealçar todas as ocorrências e a atual de maneira diferente e, invocando s, avançará e rretrocederá?
doctorate

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.