Не работает с кириллицей.

Тема в разделе "Регулярные выражения", создана пользователем Evg, 28 июл 2017.

Модераторы: xpert13
  1. Evg

    Evg Постоялец

    Регистр.:
    3 авг 2006
    Сообщения:
    97
    Симпатии:
    27
    Какие есть идеи о том, как переписать?

    Код:
    censorRegexp = new RegExp("(\\b(?:(hello)|(Здравствуйте))\\b)(?![^\\(]*\\))", "ig");


    Заранее благодарен.
     
    Последнее редактирование: 28 июл 2017
  2. lag

    lag

    Регистр.:
    13 окт 2014
    Сообщения:
    215
    Симпатии:
    280
    Метасимвол \b обозначает границу слова, а в JavaScript к слову \w относятся символы [a-zA-Z0-9_] так что для кирилицы \b не работает.
    Проверить границу слова можно так (^|[^\wА-ЯЁ]) и (?![\wА-ЯЁ]).

    Исходный фрагмент
    Код:
        try {
          censorRegexp = new RegExp("(\\b(?:" + patterns.join("|") + ")\\b)(?![^\\(]*\\))", "ig");
    
          if (censorRegexp) {
    
            return function(text) {
              let original = text;
    
              try {
                let m = censorRegexp.exec(text);
    
                while (m && m[0]) {
                  if (m[0].length > original.length) { return original; } // regex is dangerous
                  const replacement = new Array(m[0].length+1).join(replacementLetter);
                  text = text.replace(new RegExp(`(\\b${escapeRegexp(m[0])}\\b)(?![^\\(]*\\))`, "ig"), replacement);
                  m = censorRegexp.exec(text);
                }
    
                return text;
              } catch (e) {
                return original;
              }
            };
    
    Исправить на такой
    Код:
        try {
          censorRegexp = new RegExp("(^|[^\wА-ЯЁ])(?:" + patterns.join("|") + ")(?![\wА-ЯЁ])(?![^\\(]*\\))", "ig");
    
          if (censorRegexp) {
    
            return function(text) {
              let original = text;
    
              try {
            
                text = text.replace(
                    censorRegexp,
                    function(m0, m1) {
                        return m1 + new Array(m0.length - m1.length + 1).join(replacementLetter);
                    });
          
                return text;
              } catch (e) {
                return original;
              }
            };
    
     
    Последнее редактирование: 29 июл 2017
  3. Evg

    Evg Постоялец

    Регистр.:
    3 авг 2006
    Сообщения:
    97
    Симпатии:
    27
    Этот вариант не подойдет. Замены A-Я... Alnum предлагал, они пишут что это частные случаи. Замену b - предлагал, оригинальный пост:

    This does not look like a regression, I think it never worked:
    This regex4 does not work with Cyrillic .
    Anyone have any ideas on how to rewrite:
    censorRegexp = ну и т.д.
    So it does not use \b which is unsupported Russian.
    (be sure to reply here with a tested regex I have already seen the posts on Stack Overflow)

    Это все пишет разработчик Stack Overflow, и его владелец. Что-то видимо не просто. Они не "дергаются" т.к. для англ. аудитории проблем нет. А быстрое решение для многоязычной аудитории их не устраивает... Вот почему везде и спрашиваю... На всех форумах.
     
    Последнее редактирование: 29 июл 2017
  4. lexaz44

    lexaz44 Создатель

    Регистр.:
    21 мар 2017
    Сообщения:
    9
    Симпатии:
    0
    C utf-8 не заработает. Если только предварительно конвертировать в cp-1251, там обрабатывать и обратно в utf-8. Извращение, но работает
     
  5. Evg

    Evg Постоялец

    Регистр.:
    3 авг 2006
    Сообщения:
    97
    Симпатии:
    27
    Однозначно должен быть способ универсальный. Представлены языки и китайский, персидский и т.д. Т.е. надо универсальный метод... Пока отложили это.