[js] состоит ли строка из одной буквы с учетом локализации
От: DmitryShm Россия  
Дата: 23.06.10 02:50
Оценка:
В связи с портированием программы из С++ в JavaScript встала задача написать аналог фукнции isalpha. Вот что сразу пришло на ум.


function isalpha(c)
{
    if (typeof c == "string")
    {
        if (c.length == 1)
        {
             //здесь один символ в строке, проверяем его на буквенность
             return (c.match(/\w/) != null);
        }
        else
        {
            return false;
        }
    }
    else
    {
        return false;
    }
    return c.length
}


Но проблема в том, что функция работает лишь только с ASCII символами из-за регулярного выражения. Как бы написать такую функцию, которая работала бы, например, с русскими буквами (вариантов с перебором по вручную созданному массиву букв лучше не предлагать --- для всех локализаций так не насоздаешь).
Re: [js] состоит ли строка из одной буквы с учетом локализац
От: DmitryShm Россия  
Дата: 23.06.10 02:52
Оценка:
Здравствуйте, DmitryShm, Вы писали:

DS> return c.length


опечатка
Re: [js] состоит ли строка из одной буквы с учетом локализац
От: DmitryShm Россия  
Дата: 23.06.10 03:04
Оценка:
Пока лучшее, что приходит на ум в случае с русскими буквами. Теперь придумать бы для любой локализации. Должен быть какой-то модуль, работающий с этим.
return (c.match(/[а-яА-Яa-zA-Z]/) != null);
Re: [js] состоит ли строка из одной буквы с учетом локализац
От: c-smile Канада http://terrainformatica.com
Дата: 23.06.10 04:30
Оценка:
Здравствуйте, DmitryShm, Вы писали:

DS>В связи с портированием программы из С++ в JavaScript встала задача написать аналог фукнции isalpha. Вот что сразу пришло на ум.


Прямого метода нет.

По идее можно использовать пару toLowerCase()/toUpperCase()
Для всех alpha должно давать разные коды (charCodeAt()) — справедливо для всех романских языков и кириллицы.
Не идеально конечно но хоть что-то.
Re[2]: [js] состоит ли строка из одной буквы с учетом локали
От: Centaur Россия  
Дата: 23.06.10 06:39
Оценка:
Здравствуйте, c-smile, Вы писали:

CS>По идее можно использовать пару toLowerCase()/toUpperCase()

CS>Для всех alpha должно давать разные коды (charCodeAt()) — справедливо для всех романских языков и кириллицы.
CS>Не идеально конечно но хоть что-то.

Не будет работать с каной и иероглифами, как минимум.
Не будет работать с алфавитами, не различающими прописных и строчных букв (например: иврит, арабский, лаосский).
Re: [js] состоит ли строка из одной буквы с учетом локализац
От: Centaur Россия  
Дата: 23.06.10 07:07
Оценка:
Здравствуйте, DmitryShm, Вы писали:

DS>В связи с портированием программы из С++ в JavaScript встала задача написать аналог фукнции isalpha. Вот что сразу пришло на ум.


DS>        if (c.length == 1)


Не будет работать с decomposed представлениями букв с диакритическими знаками (например: U+00C1 (Latin Capital Letter A With Acute) === U+0041 U+0301 (Latin Capital Letter A + Combining Acute Accent)). А перевести всё в composite не всегда возможно (например, для кириллицы с ударениями нет композитных форм).

Цитирую из стандарта Unicode, глава 4, стих 5, General Category—Normative:

This property is also used to support common APIs such as isDigit(). Common functions such as isLetter() and isUppercase() do not extend well to the larger and more complex repertoire of Unicode. While it is possible to naively extend these functions to Unicode using the General_Category and other properties, they will not work for the entire range of Unicode characters and range of tasks for which people use them. For more appropriate approaches, see Unicode Standard Annex #31, “Unicode Identifier and Pattern Syntax”; Unicode Standard Annex #29, “Unicode Text Segmentation”; Section 5.18, Case Mappings; and Section 4.10, Letters, Alphabetic, and Ideographic.


То есть, в зависимости от того, для чего вам понадобилась функция isalpha:
Re[2]: [js] состоит ли строка из одной буквы с учетом локали
От: Аноним  
Дата: 23.06.10 07:37
Оценка:
Здравствуйте, Centaur, Вы писали:

/^[[:alpha:]]$/, не?
Re[3]: [js] состоит ли строка из одной буквы с учетом локали
От: Centaur Россия  
Дата: 23.06.10 10:18
Оценка:
Здравствуйте, Аноним, Вы писали:

А>/^[[:alpha:]]$/, не?


Я тоже так думал. Но в действующем стандарте ECMA-262 5th Edition:

CharacterClass ::
    [ [lookahead ∉ {^}] ClassRanges ]
    [ ^ ClassRanges ]
 
ClassRanges ::
    [empty]
    NonemptyClassRanges

NonemptyClassRanges ::
    ClassAtom
    ClassAtom NonemptyClassRangesNoDash

ClassAtom
    -
    ClassAtom ClassRanges

NonemptyClassRangesNoDash ::
    ClassAtom
    ClassAtomNoDash NonemptyClassRangesNoDash
    ClassAtomNoDash - ClassAtom ClassRanges

ClassAtom ::
    -
    ClassAtomNoDash

ClassAtomNoDash ::
    SourceCharacter but not one of \ or ] or -
    \ ClassEscape


POSIX Character Classes (вида [:xxx:]) нигде не упомянуты. Perl’овые Unicode property tests (вида \p{xxx}) тоже.

Also, в perldoc perlrecharclass написано:

Perl recognizes the following POSIX character classes:

[list=1]

  • alpha Any alphabetical character ("[A-Za-z]").
  • alnum Any alphanumerical character. ("[A-Za-z0-9]")


  • Also, в документации на developer.mozilla.org про Javascript/Regular Expressions тоже нигде не написано, что поддерживаются POSIX character classes или Unicode property tests.
    Re[4]: [js] состоит ли строка из одной буквы с учетом локали
    От: Аноним  
    Дата: 23.06.10 10:38
    Оценка:
    Здравствуйте, Centaur, Вы писали:

    C>Also, в perldoc perlrecharclass написано:

    C>[q]Perl recognizes the following POSIX character classes:

    C>[list=1]
  • alpha Any alphabetical character ("[A-Za-z]").

    Странно, у меня а том же самом просто "Any alphabetical character", без ограничений. ActiveState Perl 5.8.9 for Win32
  • Re[4]: [js] состоит ли строка из одной буквы с учетом локали
    От: Аноним  
    Дата: 23.06.10 10:45
    Оценка:
    Здравствуйте, Centaur, Вы писали:

    C>Я тоже так думал. Но в действующем стандарте ECMA-262 5th Edition:


    C>

    C>CharacterClass ::
    C>    [ [lookahead ∉ {^}] ClassRanges ]
    C>    [ ^ ClassRanges ]
     
    C>ClassRanges ::
    C>    [empty]
    C>    NonemptyClassRanges
    
    C>NonemptyClassRanges ::
    C>    ClassAtom
    C>    ClassAtom NonemptyClassRangesNoDash
    
    C>ClassAtom
    C>    -
    C>    ClassAtom ClassRanges
    
    C>NonemptyClassRangesNoDash ::
    C>    ClassAtom
    C>    ClassAtomNoDash NonemptyClassRangesNoDash
    C>    ClassAtomNoDash - ClassAtom ClassRanges
    
    C>ClassAtom ::
    C>    -
    C>    ClassAtomNoDash
    
    C>ClassAtomNoDash ::
    C>    SourceCharacter but not one of \ or ] or -
    C>    \ ClassEscape 
    C>


    C>POSIX Character Classes (вида [:xxx:]) нигде не упомянуты. Perl’овые Unicode property tests (вида \p{xxx}) тоже.


    Ладно, посмотрю у Фридла в MRE, когда получу к ней доступ
    Re[5]: [js] состоит ли строка из одной буквы с учетом локали
    От: Centaur Россия  
    Дата: 23.06.10 11:37
    Оценка:
    Здравствуйте, Аноним, Вы писали:

    C>>Also, в perldoc perlrecharclass написано:

    Perl recognizes the following POSIX character classes:

    1. alpha Any alphabetical character ("[A-Za-z]").


    А>Странно, у меня а том же самом просто "Any alphabetical character", без ограничений. ActiveState Perl 5.8.9 for Win32


    Я смотрю на perldoc.perl.org, там (предположительно) самая свежая версия. И там ещё приписка:

    Both the \p forms are unaffected by any locale that is in effect, or whether the string is in UTF-8 format or not, or whether the platform is EBCDIC or not. In contrast, the POSIX character classes are affected. If the source string is in UTF-8 format, the POSIX classes (with the exception of [:punct:]], see Note [5]) behave like their "Full-range" Unicode counterparts. If the source string is not in UTF-8 format, and no locale is in effect, and the platform is not EBCDIC, all the POSIX classes behave like their ASCII-range counterparts. Otherwise, they behave based on the rules of the locale or EBCDIC code page. It is proposed to change this behavior in a future release of Perl so that the the UTF8ness of the source string will be irrelevant to the behavior of the POSIX character classes. This means they will always behave in strict accordance with the official POSIX standard. That is, if either locale or EBCDIC code page is present, they will behave in accordance with those; if absent, the classes will match only their ASCII-range counterparts.


    В не самых свежих написано так:

    The exact set of characters matched depends on whether the source string is internally in UTF-8 format or not. See Locale, Unicode and UTF-8.

    The rule is that if the source string is in UTF-8 format, the character classes match according to the Unicode properties. If the source string isn't, then the character classes match according to whatever locale is in effect. If there is no locale, they match the ASCII defaults (52 letters, 10 digits and underscore for \w, 0 to 9 for \d, etc).


    Короче, всё сложно, а чтобы было просто, нужно всегда использовать \p{xxx}.

    Впрочем, это про Perl, а исходный вопрос был про Javascript. А там ни той, ни другой формы вообще нет.
    Re[3]: [js] состоит ли строка из одной буквы с учетом локали
    От: c-smile Канада http://terrainformatica.com
    Дата: 23.06.10 19:14
    Оценка:
    Здравствуйте, Centaur, Вы писали:

    C>Не будет работать с каной и иероглифами, как минимум.

    C>Не будет работать с алфавитами, не различающими прописных и строчных букв (например: иврит, арабский, лаосский).

    Ну давай я еще раз повторю сообщение для тех кто в танке. И выделю в этот раз:

    1) Прямого метода нет.
    2) Справедливо для всех романских языков и кириллицы.
    3) Не идеально конечно но хоть что-то.
    Re[4]: [js] состоит ли строка из одной буквы с учетом локали
    От: Centaur Россия  
    Дата: 25.06.10 05:39
    Оценка:
    Здравствуйте, c-smile, Вы писали:

    CS>Ну давай я еще раз повторю сообщение для тех кто в танке. И выделю в этот раз:


    CS>1) Прямого метода нет.

    CS>2) Справедливо для всех романских языков и кириллицы.
    CS>3) Не идеально конечно но хоть что-то.


    Ну так я разверну мысль. То, что прямого метода нет — повод переосмыслить задачу, учитывая контекст более высокого уровня. Многие задачи, которые в однобайтных кодировках делаются целиком и полностью через isalpha, в юникоде надо делать по-другому.
    Re[5]: [js] состоит ли строка из одной буквы с учетом локали
    От: slava_phirsov Россия  
    Дата: 25.06.10 06:07
    Оценка:
    Здравствуйте, Centaur, Вы писали:

    C>Ну так я разверну мысль. То, что прямого метода нет — повод переосмыслить задачу, учитывая контекст более высокого уровня. Многие задачи, которые в однобайтных кодировках делаются целиком и полностью через isalpha, в юникоде надо делать по-другому.


    Можно еще дополнение? Я конечно, могу быть очень неправ, поправьте, если что, только сильно не ругайтесь... Тут еще не поднималась мысль о том, что кодировки юникода могут быть разными (UTF, UCS с различными endian-ами). Так что, выходит, если и в самом деле не поддерживается в JavaScript регулярных выражениях юникодовские фичи, и требуется суровое сравнение на уровне отдельных байт, то гемор разрастается до размеров арбуза средней величины.
    Люди! Люди, смотрите, я сошел с ума! Люди! Возлюбите друг друга! (вы чувствуете, какой бред?)
    Re[6]: [js] состоит ли строка из одной буквы с учетом локали
    От: anonymous Россия http://denis.ibaev.name/
    Дата: 25.06.10 14:01
    Оценка:
    Здравствуйте, slava_phirsov, Вы писали:

    C>>Ну так я разверну мысль. То, что прямого метода нет — повод переосмыслить задачу, учитывая контекст более высокого уровня. Многие задачи, которые в однобайтных кодировках делаются целиком и полностью через isalpha, в юникоде надо делать по-другому.

    _>Можно еще дополнение? Я конечно, могу быть очень неправ, поправьте, если что, только сильно не ругайтесь... Тут еще не поднималась мысль о том, что кодировки юникода могут быть разными (UTF, UCS с различными endian-ами). Так что, выходит, если и в самом деле не поддерживается в JavaScript регулярных выражениях юникодовские фичи, и требуется суровое сравнение на уровне отдельных байт, то гемор разрастается до размеров арбуза средней величины.

    Нет, внутреннее представление строк JavaScript в UTF-8.
    Re[7]: [js] состоит ли строка из одной буквы с учетом локали
    От: c-smile Канада http://terrainformatica.com
    Дата: 25.06.10 16:29
    Оценка:
    Здравствуйте, anonymous, Вы писали:

    A>Нет, внутреннее представление строк JavaScript в UTF-8.


    Тебя нагло обманули.

    Прямо на первой странице Ecma-262 :

    A conforming implementation of this International standard shall interpret characters in conformance with the
    Unicode Standard, Version 2.1 or later, and ISO/IEC 10646-1 with either UCS-2 or UTF-16 as the adopted
    encoding form, implementation level 3. If the adopted ISO/IEC 10646-1 subset is not otherwise specified, it is
    presumed to be the BMP subset, collection 300. If the adopted encoding form is not otherwise specified, it
    presumed to be the UTF-16 encoding form.


    UCS-2 это 16-bit code points.
    UTF-16 это 16-bit code units.

    Т.е. строка в JS это всегда последовательность как минимум 16-бит значений.
    Re[5]: [js] состоит ли строка из одной буквы с учетом локали
    От: c-smile Канада http://terrainformatica.com
    Дата: 25.06.10 16:35
    Оценка:
    Здравствуйте, Centaur, Вы писали:

    C>Ну так я разверну мысль. То, что прямого метода нет — повод переосмыслить задачу, учитывая контекст более высокого уровня. Многие задачи, которые в однобайтных кодировках делаются целиком и полностью через isalpha, в юникоде надо делать по-другому.


    Я тебя не понимаю.

    UNICODE database включает isletter*** аттрибут для каждого символа.

    Вот из моей имплементации JavaScript alike языка:
    http://code.google.com/p/tiscript/source/browse/trunk/tool/ucdata/ucdata_lt.h

    См. ucisalpha


    #define UC_LU 0x00004000 /* Letter, Uppercase          */
    #define UC_LL 0x00008000 /* Letter, Lowercase          */
    #define UC_LT 0x00010000 /* Letter, Titlecase          */
    #define UC_LM 0x00020000 /* Letter, Modifier           */
    #define UC_LO 0x00040000 /* Letter, Other              */
    
    #define ucisalpha(cc) ucisprop(cc, UC_LU|UC_LL|UC_LM|UC_LO|UC_LT, 0)
    Re[7]: [js] состоит ли строка из одной буквы с учетом локали
    От: slava_phirsov Россия  
    Дата: 28.06.10 11:51
    Оценка:
    Здравствуйте, anonymous, Вы писали:

    A>Нет, внутреннее представление строк JavaScript в UTF-8.



    1. А если у страницы (если мы рассматриваем страницу, на которой сидит скрипт), charset указан не utf-8? Предполагается, что браузер все разрулит и преобразует в нужную кодировку?
    2. Можно при наличии воображения представить себе скрипт, который считывает внешний файл (насколько я помню, реализация может расширять стандарт) или что-то в этом роде, короче говоря, источник данных — снаружи, и кодировка у него может быть вообще какая угодно. Ну вот такой юзкейз: от внешнего источника последовательно приходят символы, а наш скрипт при помощи функции isalpha, разрабатываемой топикстартером, должен определить, является ли очередной символ буквой, или нет. Пример, конечно, надуманный...
    Люди! Люди, смотрите, я сошел с ума! Люди! Возлюбите друг друга! (вы чувствуете, какой бред?)
    Re[8]: [js] состоит ли строка из одной буквы с учетом локали
    От: anonymous Россия http://denis.ibaev.name/
    Дата: 28.06.10 14:44
    Оценка:
    Здравствуйте, c-smile, Вы писали:

    A>>Нет, внутреннее представление строк JavaScript в UTF-8.

    CS>Прямо на первой странице Ecma-262 :
    CS>Т.е. строка в JS это всегда последовательность как минимум 16-бит значений.

    Да, ты прав, UTF-16.
     
    Подождите ...
    Wait...
    Пока на собственное сообщение не было ответов, его можно удалить.