วิธีค้นหาคำภาษาอาหรับในข้อความโดยไม่มีการกำกับเสียง / การออกเสียง


11

ในภาษาอาหรับเช่นเดียวกับภาษาอื่น ๆ มีสิ่งที่เรียกว่าการกำกับเสียงเพื่อปรับปรุงการออกเสียง ไม่มีการประชุมเกี่ยวกับจำนวนกำกับควรเขียนสำหรับคำเดียว บางคนใช้ค่าต่ำสุด (ซึ่งฉันชอบ) เพียงพอที่จะทำให้การออกเสียงไม่ชัดเจนในขณะที่บางคนใช้มันอย่างฟุ่มเฟือยหรือเพียงเพื่อจุดประสงค์ด้านการประดิษฐ์ตัวอักษรที่สวยงาม ดังนั้นจึงมีความหลากหลายในสิ่งที่และจำนวนกำกับเกี่ยวข้องกับคำเดียว เมื่อฉันisearch-forward/backwardกดปุ่มC-s/rปัญหาจะเกิดขึ้นเมื่อฉันพิมพ์ลงใน mini-buffer การค้นหาโดยไม่ต้องใช้เครื่องหมายกำกับเสียงมันจะไม่ตรงกับคำเดียวกันในข้อความหากมีการกำกับออกเสียงทำให้งานค้นหาคำนี้ด้วยการกำกับออกเสียงที่อาจเกิดขึ้น

มีวิธีที่จะทำให้การค้นหา / regexp ค้นหาไม่รู้กำกับออกเสียงหรือไม่? ฉันหวังว่าจะมีคำตอบที่สามารถขยายเพื่อรวมregexp C-M-s/rและgrepค้นหาที่ฉันใช้บ่อยในหางเสือ - projectile เพื่อค้นหาคำในโครงการยางหลายไฟล์

อัปเดต
มันน่ายินดีที่ได้เห็นว่า Emacs ในฟังก์ชั่นการค้นหาทั้งหมดทำขั้นตอนการถอดลอกข้อความ (จากการเน้นเสียง / การกำกับ / คุณตั้งชื่อ) ก่อนการจับคู่ขั้นตอนเป็นพฤติกรรมเริ่มต้นที่อาจถูกปิดโดยคำนำหน้า ไม่ว่าจะใช้ภาษาใด โดยทั่วไปเมื่อฉันค้นหาสิ่งที่ฉันไม่คาดหวังจากตัวแก้ไขที่ดีที่สุด (Emacs) ที่จะล้มเหลวในการทำธุระนี้เพียงเพราะการกำกับหรือการเน้นเสียงบางอย่างที่ไม่ค่อยได้รับถ้าจำเป็นเพื่อให้ได้งานเขียนข้อความธรรมดา ๆ


1
ดูucs-normalize-*ฟังก์ชั่นlisp/international/ucs-normalize.elค่ะ ไม่มีการย่อการค้นหาที่กำหนดไว้ล่วงหน้าสำหรับสิ่งเหล่านั้นเช่นเดียวกับการพับตัวพิมพ์เล็ก แต่อย่างน้อยคุณสามารถทำให้มาตรฐานเป็นปกติในภูมิภาคก่อนค้นหา การใช้งานที่ดีอาจเป็นงานที่ค่อนข้างซับซ้อน
Ted Zlatanov

superuser.com/a/675172/233868สามารถช่วยได้หรือไม่?
ชื่อ

@Name, ภาษาอาหรับมีความเป็นไปได้มากขึ้นในการรวมตัวอักษร (26) เข้ากับสำเนียง / การกำกับเสียงดังนั้นจึงไม่ใช่ภาษาอาหรับ ดูเหมือนว่าไม่มีการแทนที่ห้องสมุดเฉพาะภาษา ฉันไม่อยากเชื่อเลยว่าสิ่งนี้ได้ถูกนำไปใช้ใน Microsoft Word แล้วและไม่ได้อยู่ใน Emacs ตลอดหลายปีที่ผ่านมา
ปริญญาเอก

1
ภาษาอาหรับมีเครื่องหมายกำกับ 80 ตัวและตัวอักษร 26 ตัวทำให้การผสมทั้งหมดเป็นงานที่น่ากลัว ต้องมีวิธีที่จะตัดข้อความของนักออกเสียงกำกับเช่นเดียวกับสิ่งที่phpนำไปใช้งาน: stackoverflow.com/a/25563250/1288722 - นำมาใช้ในJavascript: stackoverflow.com/a/7193622/1288722
ปริญญาเอก

ความคิด: มันเป็นไปไม่ได้ไหมที่จะรันสตริงผ่านฟังก์ชั่นทำความสะอาด php แล้วส่งผลให้บางสิ่งที่คล้ายกันhelm-swoopหรือไม่
ฌอน Allred

คำตอบ:


5

นี่เป็นจุดเริ่มต้นคร่าวๆโดยอ้างอิงจากรายการการรวมอักขระในคำตอบนี้ (จากนั้นขยาย) (ทำเครื่องหมายว่านี่เป็นวิกิชุมชน - โปรดแก้ไขและปรับปรุงสิ่งนี้!)

(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)))

ดังนั้นหากบัฟเฟอร์มี "الْحَمْدُ لِلَّهِ رَبِّ الْعَالَمِينَ" และฉันประเมิน(arabic-search-without-diacritics "الحمد لله رب العالمين")แล้วมันก็พบข้อความ มันยังทำงานแบบโต้ตอบเช่นM-x arabic-search-without-diacriticsกัน

ทางเลือกวิธีการ:

ต่อไปนี้เป็นตัวอย่างโค้ดแบบเต็มที่แสดงให้เห็นว่าMnสามารถลบเครื่องหมายกำกับ ( คุณสมบัติ) และเครื่องหมายกำกับและอื่น ๆจากสตริงปกติในการจับคู่ regexp มันทำงานร่วมกับตัวอย่างที่กำหนดและ IMO เป็นวิธีการที่เหมาะสม

(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)))

ฉันได้เพิ่มการกำกับอีกสองรายการที่ใช้โดยทั่วไปในภาษาอาหรับเข้ากับรายการที่ดีของคุณ นี่คือรายการที่สมบูรณ์เรียงแล้ว1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1648- ฟรีค่าธรรมเนียมในการอัปเดต
ปริญญาเอก

ฟังก์ชั่นแรกที่arabic-search-without-diacriticsทำงานได้ดี الأَแต่แบ่งด้วยคำพูดบางอย่างผมไม่ทราบว่าทำไมเช่นนี้ ข้อแม้อื่น ๆ ฉันมักจะตั้งวิธีการป้อนข้อมูลเป็นภาษาอาหรับเมื่อฉันป้อนสตริงของฉันในมินิบัฟเฟอร์ในขณะที่isearch-forward/backwardฟังก์ชั่นมันยังคงอยู่ที่นั่น
ปริญญาเอก

kill-marksเป็นวิธีที่ดีกว่าในการเตรียมข้อความที่ไม่ยุ่งยากให้พร้อมสำหรับการค้นหาทุกประเภท สิ่งที่ไม่ชัดเจนสำหรับฉันคือวิธีการนำไปใช้กับบัฟเฟอร์ทั้งหมดและจากหลายไฟล์
ปริญญาเอก

1
ขอบคุณ! เป็นไปได้ไหมที่จะทำให้มันเหมือนเป็นisearch-forward/backwardไฮไลต์ที่เกิดขึ้นทั้งหมดและสิ่งที่เกิดขึ้นในปัจจุบันนั้นแตกต่างกันไปและการเรียกใช้sจะเลื่อนไปข้างหน้าและrย้อนกลับ
ปริญญาเอก

2
การสนทนาเกี่ยวกับ emacs-devel: thread.gmane.org/gmane.emacs.devel/182483
Ted Zlatanov
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.