דילוג לתוכן
  • דף הבית
  • קטגוריות
  • פוסטים אחרונים
  • משתמשים
  • חיפוש
  • חוקי הפורום
כיווץ
תחומים

תחומים - פורום חרדי מקצועי

💡 רוצה לזכור קריאת שמע בזמן? לחץ כאן!
  1. דף הבית
  2. תכנות
  3. איך להסיר ניקוד וטעמים מטקסט בc#

איך להסיר ניקוד וטעמים מטקסט בc#

מתוזמן נעוץ נעול הועבר תכנות
7 פוסטים 4 כותבים 519 צפיות
  • מהישן לחדש
  • מהחדש לישן
  • הכי הרבה הצבעות
התחברו כדי לפרסם תגובה
נושא זה נמחק. רק משתמשים עם הרשאות מתאימות יוכלו לצפות בו.
  • pcinfogmachP מנותק
    pcinfogmachP מנותק
    pcinfogmach
    כתב ב נערך לאחרונה על ידי
    #1

    איך להסיר ניקוד וטעמים מטקסט בc#
    מצאתי שני דרכים אשמח לקבל המלצות איזה עדיף ולמה.


    # אפשרות א על ידי רגקס


      public static string RemoveDiactricts(string input)
      {
          return Regex.Replace(input, @"\p{M}", "");
      }
    

    # אפשרות ב על ידי ספריית Diactricts


    דרך ה-NuGet התקינו את ספריית Diactricts
    83681b5d-4110-4701-9f7a-9d0e93b958b9-image.png
    לאחמ"כ תוכלו להתשמש עם ה-class דלהלן

     public class HebrewDiacriticsMapping : IAccentMapping
     {
         private readonly Dictionary<char, MappingReplacement> mappings;
    
         public HebrewDiacriticsMapping()
         {
             mappings = CreateMappings();
         }
    
         public IDictionary<char, MappingReplacement> Mapping => mappings;
    
         private Dictionary<char, MappingReplacement> CreateMappings()
         {
             var mappings = new Dictionary<char, MappingReplacement>();
    
             // Remove all Hebrew diacritics by mapping them to an empty string
             // Diacritics in Hebrew range from U+0591 to U+05BD, U+05C1, U+05C2, U+05C4, U+05C5
             // U+0591 - U+05AF (excluding U+05BE - U+05C0, which are vowels and other symbols)
             // U+05B0 - U+05BD, U+05C1, U+05C2, U+05C4, U+05C5 (including additional diacritics)
             for (int i = 0x0591; i <= 0x05AF; i++)
             {
                 char diacriticChar = (char)i;
                 mappings[diacriticChar] = new MappingReplacement();
             }
             for (int i = 0x05B0; i <= 0x05BD; i++)
             {
                 char diacriticChar = (char)i;
                 mappings[diacriticChar] = new MappingReplacement();
             }
             mappings['\u05C1'] = new MappingReplacement();
             mappings['\u05C2'] = new MappingReplacement();
             mappings['\u05C4'] = new MappingReplacement();
             mappings['\u05C5'] = new MappingReplacement();
    
             return mappings;
         }
     }
    
     public static class HebrewDiacriticsRemover
     {
         private static readonly DiacriticsMapper mapper = new DiacriticsMapper(new HebrewDiacriticsMapping());
         public static string RemoveHebrewDiacritics(this string input)
         {
             return mapper.RemoveDiacritics(input);
         }
     }
    

    גמ"ח מידע מחשבים ואופיס

    תגובה 1 תגובה אחרונה
    1
    • dovidD מנותק
      dovidD מנותק
      dovid ניהול
      כתב ב נערך לאחרונה על ידי dovid
      #2

      קשה להבין את השאלה שלך, למה יש לך צד שהשימוש בספריה עדיף?
      במיוחד שהשימוש בספריה לא חוסך קוד אלא מוסיף.
      להשתמש בספריה יש בזה מחירים: תלות, תחזוקה (אם קיימת) בשליטה חיצונית, אבטחה. לא משלמים את המחירים האלו בלי תמורה (עריכה: הספריה מהירה יותר מRegex בשליש בערך, ראה להלן).

      בשביל הספורט בדקתי ביצועים של האפשרויות שעלו לי בראש, להלן הקוד:

      class Test
      {
          string text;
          public Test()
          {
              System.Text.Encoding.RegisterProvider(System.Text.CodePagesEncodingProvider.Instance);
              text = File.ReadAllText(@"D:\Tora\020_MISHNA\101_SEDER_MOED\13_MAS_ERUVIN\MZ2_ERUVIN_L2.txt", Encoding.GetEncoding(1255));
          }
      
      
          string byRegex()                => Regex.Replace(text, @"\p{M}", "");
          string byRegexDedicated()       => Regex.Replace(text, @"[\u0591-\u05CF]", "");
          string byDiacritis()            => text.RemoveHebrewDiacritics();
          string byLinqReverseCondition() => new string(text.Where(x => x < 1425 || x > 1487).ToArray());
          string byLinq()                 => new string(text.Where(x => x > 1487 || x < 1425).ToArray());
      
          string byStringBuilder()
          {
              var sb = new StringBuilder(text.Length);
              foreach (var c in text)
                  if (c > 1487 || c < 1425)
                      sb.Append(c);
      
              return sb.ToString();
          }
      }
      
      }
      

      תוצאות:

      הסבר:
      הטסט הוא על קובץ של ברטנורא מנוקד על עירובין מתוך תורת אמת.
      יש פה חמישה דרכים, הראשונה (byRegex) היא Regex גנרי שמתאים לכל סימני הניקוד בעולם (כולל למשל גרמנית), השניה מטפלת בניקוד עברי בלבד שזה לעצמו חיסכון אבל הוא זניח כי עיקר הזמן הוא ההחלפה בפועל שלא יעילה יותר.
      הדרך השלישית שזה הספריה שהוצעה, אכן מביאה שיפור בביצועים לעומת רגקס. היא כנראה כתובה הכי טוב שאפשר אבל היא גנרית מידי וכנראה לכן היא מפסידה לשיטות האחרות.
      הדרך הרביעית והחמישית (byLinq) זהות מצד השיטה, הם בודקים אם האות בטווח התווים של הניקוד העברי, ההבדל ביניהם הוא רק בסדר התנאי, בהנחה שרוב האויות שייבדקו הם אותיות עבריות דוקא שערכם גדול מ1488 (האות א) אז יעיל קודם לבדוק אם האות גדולה מהערך הזה ולהימנע מבדיקה נוספת, אני לא מבין למה הדרך שנראאית לי פחות יעילה מהירה יותר עקבית אבל בהפרש זניח.
      הדרך האחרונה זה עבודה שחורה, זה נראה הכי מהר.

      מה הייתי עושה? לפני הבדיקה הייתי לבטח משתמש בRegex כנראה, בגלל הקריאות והפשטות. אחריה? יש לי יצר להיות יעיל יותר, אבל זה פחות לגיטימי מרג'קס במקרים שיעילות לא נדרשת בדחיפות.

      מנטור אישי למתכנתים (ולא רק) – להתקדם לשלב הבא!

      בכל נושא אפשר ליצור קשר dovid@tchumim.com

      pcinfogmachP 2 תגובות תגובה אחרונה
      7
      • dovidD מנותק
        dovidD מנותק
        dovid ניהול
        כתב ב נערך לאחרונה על ידי dovid
        #3

        ערכתי דרמטית את ההודעה שלי בגלל שבקוד המקורי קראתי את הקובץ כUTF8 בעוד הוא windows-1255 וממילא לא היה בו שום ניקוד. זה שינה מאוד את התוצאות כי לא היו החלפות בכלל.
        גם כעת הוספתי Regex ייעודי לעברית.

        מנטור אישי למתכנתים (ולא רק) – להתקדם לשלב הבא!

        בכל נושא אפשר ליצור קשר dovid@tchumim.com

        תגובה 1 תגובה אחרונה
        4
        • pcinfogmachP מנותק
          pcinfogmachP מנותק
          pcinfogmach
          השיב לdovid ב נערך לאחרונה על ידי pcinfogmach
          #4

          @dovid
          פשוט אין מילים!
          אפשר לשאול איך עשית את הבדיקות? זה נראה שהתשמשת באיזשהו תוכנה לא visual studio

          כמו"כ אפשר לשאול למה בעצם על ידי string builder הוא הכי מהיר מכולם?

          גמ"ח מידע מחשבים ואופיס

          M תגובה 1 תגובה אחרונה
          0
          • M מנותק
            M מנותק
            mekev
            השיב לpcinfogmach ב נערך לאחרונה על ידי
            #5

            @pcinfogmach כתב באיך להסיר ניקוד וטעמים מטקסט בc#:

            אפשר לשאול איך עשית את הבדיקות? זה נראה שהתשמשת באיזשהו תוכנה לא visual studio

            LINQPad

            תגובה 1 תגובה אחרונה
            5
            • Aharon 0A מנותק
              Aharon 0A מנותק
              Aharon 0
              כתב ב נערך לאחרונה על ידי Aharon 0
              #6

              @dovid זה דוגמא לבדיקה לא נכונה של ביצועים.
              אני מקליד מסמארטפון ולכן קשה לי להרחיב, אנסה לתמצת:
              בקריאה לפונקציות מסוימות נדרש לפעמים למערכת הפעלה זמן דרישה להקצות משאבים.
              ולכן לא מסתכלים על זמן ריצה כולל אלא זמן הקצאה + זמן עיבוד, וההפרש בא לביטוי בעיקר בעבודה עם כמות דאטה ענקית. ולכן בדיקה נכונה של ביצועים מתבצע עם כמות דאטא קטנה וכמות דאטה ענקית (לדוגמא: ניקוד של כל התנ"ך...) ואז מעניין יהיה לראות שחלק מהפונקציות מהירות בדאטא קטן וחלק בדאטא גדול, בפוריקט מסוים בדקתי גודל של דאטא ובהתאם לכך את הפונקציה המהירה לאותה כמות.

              תגובה 1 תגובה אחרונה
              0
              • pcinfogmachP מנותק
                pcinfogmachP מנותק
                pcinfogmach
                השיב לdovid ב נערך לאחרונה על ידי
                #7

                @dovid

                יש בעיה בהסרת ניקוד וטעמים כאשר מופיע מקף עליון שצריך להחליף אותו ברוווח אחרת זה יחבר שני מילים

                הנה הקוד המתוקן עבור שימוש ב- stringbuilder

                 public static string RemoveHebrewDiactrics(this string input)
                 {
                     var sb = new StringBuilder(input.Length);
                
                     foreach (var c in input)
                         
                         if (c == '־')
                             sb.Append(' ');
                         else if (c > 1487 || c < 1425)
                
                             sb.Append(c);
                
                     return sb.ToString();
                 }
                

                גמ"ח מידע מחשבים ואופיס

                תגובה 1 תגובה אחרונה
                1

                בא תתחבר לדף היומי!
                • התחברות

                • אין לך חשבון עדיין? הרשמה

                • התחברו או הירשמו כדי לחפש.
                • פוסט ראשון
                  פוסט אחרון
                0
                • דף הבית
                • קטגוריות
                • פוסטים אחרונים
                • משתמשים
                • חיפוש
                • חוקי הפורום