דלג לתוכן הראשי
למפתחים

איך לתקן עברית הפוכה בקוד (Visual ↔ Logical)

פונקציה קצרה, ללא תלויות, שמסדרת טקסט עברי/ערבי שיצא בסדר ויזואלי חזרה לסדר לוגי. העתק-הדבק בשפה שלך.

נסה את הכלי האינטראקטיבי →

הבעיה: סדר ויזואלי מול סדר לוגי

טקסט עברי וערבי נכתב ונקרא מימין לשמאל. בזיכרון, Unicode שומר אותו בסדר לוגי - כלומר לפי סדר הקריאה. הבעיה מתחילה כשתוכנה (לרוב מנועי PDF, מערכות ישנות, או ספריות פלט גרפי) שומרת את התווים בסדר שבו הם מצוירים על המסך - מימין לשמאל הופך לרצף משמאל לימין. זה "סדר ויזואלי". כשמערכת אחרת קוראת רצף כזה ומניחה שהוא לוגי, העברית מופיעה הפוכה.

התיקון לרוב המקרים הוא היפוך מבוקר, שהוא בדיוק ההפך של אלגוריתם ה-bidi של Unicode עבור פסקה אחת:

  1. אם השורה לא מכילה תו RTL בכלל - השאר אותה כמו שהיא (כך מספר טלפון בודד לא "מתוקן" בטעות).
  2. הפוך את כל השורה.
  3. הפוך בחזרה כל רצף לטיני/מספרי, כדי שמילים באנגלית ומספרים יישארו קריאים משמאל לימין.
// input (visual order)
"World 123 םולש"
// output (logical order)
"שלום World 123"

מימוש לפי שפה

// Fix Hebrew/Arabic text stored in visual order -> logical order.
// Dependency-free. Works in the browser and Node.

const RTL = /[\u0590-\u05FF\u0600-\u06FF\u0750-\u077F\u08A0-\u08FF\uFB1D-\uFB4F\uFB50-\uFDFF\uFE70-\uFEFC]/;
const LTR_RUN = /[A-Za-z0-9\u00C0-\u024F][A-Za-z0-9\u00C0-\u024F .,:;'"\/\-_+=&%#@!?]*[A-Za-z0-9\u00C0-\u024F]|[A-Za-z0-9\u00C0-\u024F]/g;

function fixLine(line) {
  if (!RTL.test(line)) return line;            // no RTL -> leave as-is
  const flipped = [...line].reverse().join('');
  return flipped.replace(LTR_RUN, (run) => [...run].reverse().join(''));
}

export function fixReversedHebrew(text) {
  return text.replace(/\r\n?/g, '\n').split('\n').map(fixLine).join('\n');
}

הערות ומגבלות

  • הפונקציה מטפלת במקרה הנפוץ: פסקה בעברית/ערבית עם מילים באנגלית ומספרים משובצים. היא איננה מימוש מלא של UAX#9 (אלגוריתם ה-bidi של Unicode).
  • אין היפוך גליפים (סוגריים): מודל החילוץ הנפוץ שומר את התווים המקוריים בסדר ויזואלי, ולכן היפוך פשוט מספיק. היפוך נוסף של הסוגריים רק היה מקלקל את התוצאה.
  • שורה ללא תו RTL נשארת כפי שהיא - זה מונע "תיקון" שגוי של מחרוזת לטינית או מספר שעומד לבד.
  • הזיהוי של רצף לטיני כולל אותיות לטיניות מורחבות, ספרות, ופיסוק נפוץ. לטקסט עם הרבה כיוונים מקוננים מומלץ ספריית bidi מלאה (למשל ICU, fribidi, או python-bidi).
  • הקוד עובד על קוד-נקודות במישור הבסיסי (BMP), שזה כל העברית והערבית. אין צורך בטיפול מיוחד בזוגות surrogate עבור הטקסט הזה.
רק צריך לתקן קצת טקסט?
הדבק וקבל תוצאה - בלי לכתוב שורת קוד.
פתח את הכלי →