الفريق العربي للبرمجةأرشيف المنتديات · 2000 – 2023
نسخة أرشيفية للقراءة فقط — التسجيل والمشاركة مغلقان، والمحتوى محفوظ كما كان.

Api للتحويل من نص عربي او انجليزي ال Unicode

رائج
بدأه .S.T.A.L.K.E.R في 15 سبتمبر 2009 · 72 رد · 7,901 مشاهدة · في JavaSE
مشاركة: واتساب X فيسبوك تيليجرام
#26
اقتباس
عند عمل compile فانه يتم تحويل ال String الى StringBuilder والذي هو Mutable (للعلم فقط)

حقاً ؟! ما مصدر هذه المعلومة ؟

بالنسبة للـ bug فأنا نسخت سطر الكود من مشاركتك الأولى:

String s=Unicode.decode("\u0645\u062D\u0645\u062F20\u0639\u0631\u0633\u0627\u0646");

والخطأ هنا \u062F20

لكن على أي حال أظن أنه يجب على الدالة أن تحول المسافة الفارغة إلى /u0020 أليس كذلك ؟

اقتباس
دالة توجد فقط ب JDK 1.5 و فوق

نعم، وما العيب في ذلك ؟! الإصدار الخامس قديم من أواخر الـ 2004 !

بالنسبة للـ Integer.toHexString فكلامك صحيح ...

لكن الـ String الناتجة "تهضمها" الجافا بشكل صحيح دون اعتراض

بالنسبة للكودين الأخيرين فهما أفضل بكثير على ما أعتقد :D

تم تعديل هذه المشاركة بواسطة Speed_Of_Light في 22 يوليو 2010 في 19:07

#27
اقتباس
لكن على أي حال أظن أنه يجب على الدالة أن تحول المسافة الفارغة إلى /u0020 أليس كذلك ؟

لقد قمت بالرد في مشاركة سابقة:

اقتباس
بالنسبة لموضوع الماسافات,, فإن الأداة التي تدعى native2ascii والتي تاتي مع ال JDK تفعل تماما مثلما يفعل محمد عرسان,, فإنه تطبع الماسفات كما هي....
اقتباس
بالنسبة للكودين الأخيرين فهما أفضل بكثير على ما أعتقد

شكرا لك :D

#28
Speed_Of_Light كتب:

حقاً ؟! ما مصدر هذه المعلومة ؟

حاول ان تفك اي كود من بعد ال compile (ـ Decompile)

ستجد انه لا يوجد String

بل يتم استبداله ب StringBuilder

هذا في النسخ الحديثة

لكن في النسخ القديمة كان يتم استخدام ال StringBuffer

و في حال استخدام ال =+ فانه يتبع تكوين سلسلة Chain باستخدام دالة Append

http://en.wikipedia.org/wiki/StringBuffer_and_StringBuilder

اقتباس
نعم، وما العيب في ذلك ؟! الإصدار الخامس قديم من أواخر الـ 2004 !

لا عيب لكنها دالة غير متوفرة في ال JME مما يحصر هذه المكتبة للعمل فقط على JSE.

#29

لقد قمت بتفكيك الصنف وحصلت على:

import java.io.PrintStream;

public class U
{
  private static char characterDigit(int v)
  {
    String symbs = "0123456789ABCDEF";
    return symbs.charAt(v & 0xF);
  }

  private static String characterHexaValue(int v) {
    String s = "";
    s = new StringBuilder().append(s).append(characterDigit(v >> 12)).toString();
    s = new StringBuilder().append(s).append(characterDigit(v >> 8)).toString();
    s = new StringBuilder().append(s).append(characterDigit(v >> 4)).toString();
    s = new StringBuilder().append(s).append(characterDigit(v)).toString();
    return s;
  }

  private static String characterString(int val) {
    if (val == 10) {
      return "\\n";
    }
    if (val == 13) {
      return "\\r";
    }
    if (val == 92) {
      return "\\\\";
    }
    if (val == 34) {
      return "\\\"";
    }
    if ((val < 32) || (val > 126)) {
      return new StringBuilder().append("\\u").append(characterHexaValue(val)).toString();
    }
    return new StringBuilder().append((char)val).append("").toString();
  }

  private static String accumulate(String value)
  {
    String resultString = "";
    for (int index = 0; index < value.length(); ++index) {
      int chr = value.charAt(index);
      resultString = new StringBuilder().append(resultString).append(characterString(chr)).toString();
    }

    return resultString;
  }

  public static String encode(String value) {
    return accumulate(value);
  }

  public static String decode(String value) {
    StringBuilder result = new StringBuilder();
    if (value.contains("\\u")) {
      String[] valueArray = value.split("\\\\u");
      for (String s : valueArray) {
        if (s.length() == 4) {
          try {
            System.out.println(s);
            result.append((char)Integer.parseInt(s, 16));
          } catch (NumberFormatException e) {
            result.append(s);
          }
        }
        else {
          result.append(s);
        }
      }
      return result.toString();
    }
    return value;
  }
}

لاحظ عدم كفائة الكود ... أربع StringBuilders من أجل كل حرف !!

حقيقة لم أكن أعرف أن المترجم يقوم بذلك من وراء ظهري ... شكراً للمعلومة :D

#30
لاحظ عدم كفائة الكود ... أربع StringBuilders من أجل كل حرف !!

كلام سليم

شكرا على التنويه

لكن قمت بصيانة للكود ليظهر بشكل اخر، ارجو منك قرأته :

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.mosh;

public class Unicode {

    public Unicode() {
    }
    private static final String SYMBOLS = "0123456789ABCDEF";

    private static char characterDigit(int v) {
        return SYMBOLS.charAt(v & 0xf);
    }

    private static void characterHexaValue(StringBuilder buffer, int v) {
        buffer.append(characterDigit(v >> 12));
        buffer.append(characterDigit(v >> 8));
        buffer.append(characterDigit(v >> 4));
        buffer.append(characterDigit(v));
    }

    private static void characterString(StringBuilder buffer, int val) {
        if (val == 10) {
            buffer.append("\\n");
            return;
        }
        if (val == 13) {
            buffer.append("\\r");
            return;
        }
        if (val == 92) {
            buffer.append("\\\\");
            return;
        }
        if (val == 34) {
            buffer.append("\\\"");
            return;
        }
        if (val < 32 || val > 126) {
            buffer.append("\\u");
            characterHexaValue(buffer, val);
            return;
        } else {
            buffer.append((char) val);
        }
    }

    private static String accumulate(String value) {
        StringBuilder buffer = new StringBuilder();

        for (int index = 0; index < value.length(); index++) {
            int chr = value.charAt(index);
            characterString(buffer, chr);
        }

        return buffer.toString();
    }

    public static String encode(String value) {
        return accumulate(value);
    }

    public static String decode(String value) {
        StringBuilder result = new StringBuilder();
        if (value.contains("\\u")) {
            String[] valueArray = value.split("\\\\u");
            for (String s : valueArray) {
                if (s.length() == 4) {
                    try {
                        result.append((char) Integer.parseInt(s, 16));
                    } catch (NumberFormatException e) {
                        result.append(s);
                        e.printStackTrace();
                        continue;
                    }
                } else {
                    result.append(s);
                }
            }
            return result.toString();
        }
        return value;
    }
}

you have nice talent in OOP :D

#31

تعديل جيد بلا شك، لكنه ليس أفضل الموجود حتى الآن :D

وجدت bug أخرى :

عند تنفيذ هذا الكود:

        System.out.println(decode(encode("محمد عرسان من فرسان الفريق العربي للبرمجة")));

اقتباس
محم062F عرسا0646 م0646 فرسا0646 الفري0642 العرب064A للبرمجة
#32
اقتباس

private static char characterDigit(int v) {
	return SYMBOLS.charAt(v & 0xf);
}

private static void characterHexaValue(StringBuilder buffer, int v) {
	buffer.append(characterDigit(v >> 12));
	buffer.append(characterDigit(v >> 8));
	buffer.append(characterDigit(v >> 4));
	buffer.append(characterDigit(v));
}

ليه String أو StringBuffer ؟؟؟؟ لماذا لم char [] ؟؟؟؟

#34

الكود النهائي : حيث لا داعي لتشفير الاحرف الانجليزية، صحيح انها سوف تكون ابطأ، لكن سوف توفر مساحة في حجم الملفات (والله اعلم)

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.mosh;

/**
 *
 * @author MErsan
 */
public class Unicode2 {

    private final static char[] digits = {
        '0', '1', '2', '3', '4', '5',
        '6', '7', '8', '9', 'a', 'b',
        'c', 'd', 'e', 'f'
    };

    public static String decode(String s) {
        StringBuilder result = new StringBuilder();
        String[] strings = s.split("\\\\");
        for (String h : strings) {
            if (h != null && h.length() >=5 && h.startsWith("u")) {
                System.out.println(h);
                result.append((char) Integer.parseInt(h.substring(1, 5), 16));
                if (h.length() > 5) {
                    result.append(h.substring(5, h.length() ));
                }
            } else {
                result.append(h);
            }
        }
        return result.toString();
    }

    public static String encode(String text) {
        StringBuilder buffer = new StringBuilder();
        for (int i = 0; i < text.length(); i++) {
            char c = text.charAt(i);
            if (c < 32 || c > 126) {
                buffer.append(toUnsignedString(text.charAt(i)));
            } else {
                buffer.append(c);
            }
        }
        return buffer.toString();
    }

    private static String toUnsignedString(int i) {
        char[] buf = {'\\', 'u', '0', '0', '0', '0'};
        int charPos = 6;
        int shift = 4;
        int mask = 15;
        do {
            buf[--charPos] = digits[i & mask];
            i >>>= shift;
        } while (i != 0);
        return new String(buf);
    }
}

تحياتي

#35

ههههههههههههه

كل هذا النقاش حول شيء بهذا البساطة !

@ محمد عرسان:

هناك لم تعالج الـ bug التي ذكرتها بالـ decoder، لقد قمت بإصلاحها

@ هويدي :

لن تنجو من نقدي أيضاً :D

يمكن اختصار كود الطريقة getHex بشكل معتبر ! انظر:

public class Unicode {

    static final char DIGITS[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};

    public static char[] getHex(int ch) {
        char ret[] = {'0', '0', '0', '0'};

        int count = 3;

        while (ch > 0) {
            int t = ch & 0xf;
            ch >>= 4;
            ret[count--] = DIGITS[t];
        }
        return ret;
    }


    public static String encode(String value) {
        StringBuilder sb = new StringBuilder();
        for (char ch : value.toCharArray()) {
            if (Character.isWhitespace(ch)) {
                sb.append(ch);
            } else {
                sb.append("\\u").append(getHex(ch));
            }
        }
        return sb.toString();
    }

    public static String decode(String value) {
        StringBuilder result = new StringBuilder();
        String[] valueArray1 = value.split(" ");
        for (String s1 : valueArray1) {
            String[] valueArray2 = s1.split("\\\\u");
            for (String s2 : valueArray2) {
                try {
                    result.append((char) Integer.parseInt(s2, 16));
                } catch (NumberFormatException e) {
                    result.append(s2);
                    continue;
                }
            }
            result.append(" ");
        }
        return result.toString();
    }

    public static void main(String[] args) {

        System.out.println(encode("تمرين مفيد عن اختصار الكود"));
        System.out.println(decode(encode("تمرين مفيد عن اختصار الكود")));
    }
}

تم تعديل هذه المشاركة بواسطة Speed_Of_Light في 23 يوليو 2010 في 16:11

#36
اقتباس
يمكن اختصار كود الطريقة getHex بشكل معتبر ! انظر:

ههههههه, نعم ,, لكن لاحظ,, أنا كتبت هذه الدالة بالأصل لتكون عامة الإستخدام ,,, فإنها تستطيع أن تحسب ال Hex ل مثلا 3243243 :D

سؤال حقا يا شباب أرجو الإجابة عليه... لماذا تكثروا من إستخدام ال String و ال StringBuffer و ما شابه في كود low-level مثل هذا؟؟؟

و هل تعتقد حقا أن شباب SUN عندما قاموا بكتابة الكود لمثل هذه الدوال إستخدموا أيضا String و StringBuffer ....... أظن أنهم فكروا في الموضوع low-level شويه :D

#37
هويدي كتب:

ههههههه, نعم ,, لكن لاحظ,, أنا كتبت هذه الدالة بالأصل لتكون عامة الإستخدام ,,, فإنها تستطيع أن تحسب ال Hex ل مثلا 3243243 :D

سؤال حقا يا شباب أرجو الإجابة عليه... لماذا تكثروا من إستخدام ال String و ال StringBuffer و ما شابه في كود low-level مثل هذا؟؟؟

و هل تعتقد حقا أن شباب SUN عندما قاموا بكتابة الكود لمثل هذه الدوال إستخدموا أيضا String و StringBuffer ....... أظن أنهم فكروا في الموضوع low-level شويه :D

ماذا يتوجب ان نستخدم ؟

اصلا ال StringBuffer عبارة عن []char

#38
Speed_Of_Light كتب:

@ محمد عرسان:

هناك لم تعالج الـ bug التي ذكرتها بالـ decoder، لقد قمت بإصلاحها

ما المشكلة

اخر كود وضعته لم يحتوي هذه المشكلة

اتجنيت انا :wacko: :wacko:

package com.mosh;


public class Unicode {

    private final static char[] digits = {
        '0', '1', '2', '3', '4', '5',
        '6', '7', '8', '9', 'a', 'b',
        'c', 'd', 'e', 'f'
    };

    public static String decode(String s) {
        StringBuilder result = new StringBuilder();
        String[] strings = s.split("\\\\");
        for (String h : strings) {
            if (h != null && h.length() >= 5 && h.startsWith("u")) {
                System.out.println(h);
                result.append((char) Integer.parseInt(h.substring(1, 5), 16));
                if (h.length() > 5) {
                    result.append(h.substring(5, h.length()));
                }
            } else {
                result.append(h);
            }
        }
        return result.toString();
    }

    public static String encode(String text) {
        StringBuilder buffer = new StringBuilder();
        for (int i = 0; i < text.length(); i++) {
            char c = text.charAt(i);
            if (c < 32 || c > 126) {
                buffer.append(toUnsignedString(text.charAt(i)));
            } else {
                buffer.append(c);
            }
        }
        return buffer.toString();
    }

    private static String toUnsignedString(int i) {
        char[] buf = {'\\', 'u', '0', '0', '0', '0'};
        int charPos = 6;
        int shift = 4;
        int mask = 15;
        do {
            buf[--charPos] = digits[i & mask];
            i >>>= shift;
        } while (i != 0);
        return new String(buf);
    }
}

Speed_Of_Light كتب:

ههههههههههههه

كل هذا النقاش حول شيء بهذا البساطة !

سيدي حاول في الكود الذي وضعته

يبدو انه يحتوي Bug (هلأ دوري )

حاول تمرير نص يحتوي على كلا اللغتين

String s = "ABC محمد";

سيظهر الناتج بشكل خاطىء

لقد مررت لمكتبتي هذا النص :

String s = "Hello 你好 مرحبا Allô Привет";

و يحتوي على خمسة لغات منها الصيني و الروسي

و ظهرت النتيجة سليمة :P :P

تم تعديل هذه المشاركة بواسطة محمد عرسان في 23 يوليو 2010 في 14:17

#39

بالنسبة للـ bug في كودك ... فكنت قد جربت هذه النسخة منها

وبالنسبة للـ bug في كودي فهو خطأ فني بسيط :D تم التصحيح

#40

أعتقد أن StringBuilder ليست بهذه البساطة يا محمد

أعتقد أنها تحتوي على بعض التقنيات التي قد تكون مكلفة بعض الشيء

هلا راجعت الدوال التي تستخدمها وتأكدت منه ذلك

فالحزمة فعلاً بدأت تروق لي بشكل كبير

تحياتي

حزمة المحرك الإصدارة 0.8

أي أحد يجد أني ظلمته فليراسلني

وبإذن الله لو كان له حق سيأخذه

728x90.png

#41

بالفعل اخ علاء

ال StringBuilder عبارة عن مصفوفة من الاحرف []char

لقد رأيت كيفية عمله (ٍSource Code)

يقوم بالاول بناء مصفوفة احرف من 16 عنصر (في الحالة الافتراضية)

و عند الزيادة عليه يقوم بتوسعة نفسه بزيادة حجم المصفوفة و نسخ القديم و اضافة الجديد الى المصفوفة

لكن حسبما قرأت ان التعمل معه افضل بكثير من ال StringBuffer

لكنه Asynchronous لذلك هو اسرع لكن لا يجب السماح لاكثر من Thread في نفس الوقت

بعكس ال StringBuffer حيث هو Synchronized و بذلك يمكن استخدامه خلال اكثر من Thread في نفس الوقت لكنه ابطأ. 

انظر الكود التالي (و هو الصف الاب ل StringBuilder ):

دالة اضافة String :

    public AbstractStringBuilder append(String str) {
	if (str == null) str = "null";
        int len = str.length();
	if (len == 0) return this;
	int newCount = count + len;
	if (newCount > value.length)
	    expandCapacity(newCount);
	str.getChars(0, len, value, count);
	count = newCount;
	return this;
    }

ودالة توسعة المصفوفة :

    void expandCapacity(int minimumCapacity) {
	int newCapacity = (value.length + 1) * 2;
        if (newCapacity < 0) {
            newCapacity = Integer.MAX_VALUE;
        } else if (minimumCapacity > newCapacity) {
	    newCapacity = minimumCapacity;
	}
        value = Arrays.copyOf(value, newCapacity);
    }

تحياتي :)

#42

أعتقد إذن أننا يجب أن نحدد حجم للـ StringBuilder

حتى لا نتجشم إنشاء مصفوفة جديدة

(هناك مصفوفة تنشأ أول مرة عند إنشاء الـ StringBuilder ومصفوفة أخرى تنشأ إذا كان المصفوفة القديمة لا تستوعب الحروف)

وعلينا أيضاً أن نقوم بإنشاء نسخة جديدة من الموضوع بحيث تعمل online

أي يقوم المستخدم بكتابة الحرف فيتم تحويله مباشرة إلى Unicode

تحياتي

حزمة المحرك الإصدارة 0.8

أي أحد يجد أني ظلمته فليراسلني

وبإذن الله لو كان له حق سيأخذه

728x90.png

#43
اقتباس

وعلينا أيضاً أن نقوم بإنشاء نسخة جديدة من الموضوع بحيث تعمل online

أي يقوم المستخدم بكتابة الحرف فيتم تحويله مباشرة إلى Unicode

كيف يعني؟؟

ما افهمتها.

#44

المعنى كالتالي يا محمد

المستخدم يكتب كلاماً بالعربي الكلام يترجم مباشرة في كائنك

وعندما يطلب المستخدم أن يحصل على Unicode يحصل عليه مباشرة

المفيد هنا أنه ليس على المستخدم أن ينتظر حتى تجهز كامل الجملة حتى يقوم بترجمتها

والحمل هنا هو كائن يبقى في الذاكرة (الكائن الخاص بالفئة الجديدة)

لو لم تضح الصورة أخبرني وسأحاول مرة أخرى

تحياتي

حزمة المحرك الإصدارة 0.8

أي أحد يجد أني ظلمته فليراسلني

وبإذن الله لو كان له حق سيأخذه

728x90.png

#45

علاء صدقا لا اعلم اذا كنا بحاجة لذلك

انت تتكلم عن التغيير المتزامن حسب كتابة المستخدم

لكنني فحصت المكتبة بتمرير مليون حرف عربي 1,000,000 لها و قامت بتشفيرهم بأقل من ربع ثانية

اي 220 ملي ثانية (Millisecond)

هل هنالك داعي؟

#46

ماذا عن كلفة إنشاء الكائنات مثل String و StringBuilder؟

أعتقد أن نسخة رايح جاي ستقلل هذه الكلفة

على كل ربما أكون مخطئ :)

تحياتي

حزمة المحرك الإصدارة 0.8

أي أحد يجد أني ظلمته فليراسلني

وبإذن الله لو كان له حق سيأخذه

728x90.png

#47

حقا ,, موضوع تحديد حجم إبتدائي مناسب لل StringBuffer/Builder مهم جدا,,, لأن الإهمال في هذه النقطة سوف يسبب كثر من عمليات نسخ المصوفوفات (processing + memory) ...

#48
علاء الصالحي كتب:

ماذا عن كلفة إنشاء الكائنات مثل String و StringBuilder؟

أ

صدقا علاء

كلامك سليم (الرايح الجاي) :lol:

عندما عدّلت بشكل بسيييييييط جدا

زادت سرعة الكود بنسبة 30%

شيء جميل

حددت افتراضيا ان الناتج سوف يكون اربع اضعاف المدخل في عملية الترميز :lol:

و في عملية فك الترميز :lol: حددت ان الناتج سوف يكون ربعه المدخل كأفتراض .

    public static String encode(String text) {
        if (text == null || text.length() <= 0) {
            return null;
        }
        int textLen = text.length();
        StringBuilder buffer = new StringBuilder(textLen * 4);

    public static String decode(String s) {
        if (s == null || s.length() <= 0) {
            return null;
        }
        String[] strings = s.split("\\\\");
        StringBuilder result = new StringBuilder(strings.length);

تم تعديل هذه المشاركة بواسطة محمد عرسان في 24 يوليو 2010 في 22:59

#49
اقتباس

حددت افتراضيا ان الناتج سوف يكون اربع اضعاف المدخل في عملية التشفير

و في عملية فك التشفير حددت ان الناتج سوف يكون ربعه المدخل كأفتراض .

تقصد عملية ال encoding (الترميز) فهذا ليس تشفير...

#50
هويدي كتب:

تقصد عملية ال encoding (الترميز) فهذا ليس تشفير...

مبروك التفاحة

طيب يلا اشبك ياهوو

و هذا بالظبط ما اقصد

مواضيع مشابهة

عدد الزوار حالياً

المتواجدون خلال آخر دقيقتين · يتحدّث كل ٣٠ ثانية

—الإجمالي—أعضاء مسجّلون—زوار بدون تسجيل

جارٍ التحقق من المتواجدين…