Regex обрабатывает акцентированные буквы как границу слова [дубликат]

Использование примитивных типов данных, ints, создало бы истинный в обоих случаях ожидаемый результат.

Однако, поскольку вы используете объекты Integer, оператор == имеет другое значение.

В контексте объектов == проверяет, ссылаются ли переменные на одну и ту же ссылку на объект.

Чтобы сравнить значение объектов, вы должны использовать метод equals () Eg

 b2.equals(b1)

, который укажет, является ли b2 меньше, чем b1, больше или равно (проверьте API для деталей)

35
задан user1394520 14 May 2012 в 20:50
поделиться

8 ответов

У меня была аналогичная проблема, но мне пришлось заменить массив терминов. Все решения, которые я нашел, не сработали, если два слова находились в тексте рядом друг с другом (поскольку их границы перекрывались). Поэтому мне пришлось использовать небольшой модифицированный подход:

var text = "Ještě. že; \"už\" à. Fürs, 'anlässlich' že že že.";
var terms = ["à","anlässlich","Fürs","už","Ještě", "že"];
var replaced = [];
var order = 0;
for (i = 0; i < terms.length; i++) {
    terms[i] = "(^\|[ \n\r\t.,;'\"\+!?-])(" + terms[i] + ")([ \n\r\t.,;'\"\+!?-]+\|$)";
}
var re = new RegExp(terms.join("|"), "");
while (true) {
    var replacedString = "";
    text = text.replace(re, function replacer(match){
        var beginning = match.match("^[ \n\r\t.,;'\"\+!?-]+");
        if (beginning == null) beginning = "";
        var ending = match.match("[ \n\r\t.,;'\"\+!?-]+$");
        if (ending == null) ending = "";
        replacedString = match.replace(beginning,"");
        replacedString = replacedString.replace(ending,"");
        replaced.push(replacedString);
        return beginning+"{{"+order+"}}"+ending;
    });
if (replacedString == "") break;
order += 1;
}

См. Код в скрипке: http://jsfiddle.net/antoninslejska/bvbLpdos/1/

Регулярное выражение вдохновлено: http://breakthebit.org/post/3446894238/word-boundaries-in-javascripts-regular

Я могу " t сказать, что я нахожу решение элегантным ...

0
ответ дан Antonín Slejška 20 August 2018 в 10:15
поделиться

Я заметил что-то действительно странное с \b при использовании Unicode:

/\bo/.test("pop"); // false (obviously)
/\bä/.test("päp"); // true (what..?)

/\Bo/.test("pop"); // true
/\Bä/.test("päp"); // false (what..?)

Похоже, что значение \b и \B отменено, но только при использовании с не-ASCII Unicode ? Здесь может быть что-то более глубокое, но я не уверен, что это такое.

В любом случае кажется, что граница слова - это проблема, а не символы Юникода. Возможно, вам следует просто заменить \b на (^|[\s\\/-_&]), поскольку это работает правильно. (Сделайте свой список символов более всеобъемлющим, чем мой.)

2
ответ дан apsillers 20 August 2018 в 10:15
поделиться
  • 1
    \b и \B не являются Unicode-знаками в JavaScript, поэтому они считают ä не буквенно-цифровым символом и поэтому видят границу слова между p и ä. – Tim Pietzcker 14 May 2012 в 21:54

То, что вы ищете, это стандарт границ слов в Юникоде:

http://unicode.org/reports/tr29/tr29-9.html#Word_Boundaries

Здесь есть реализация JavaScript (unciodejs.wordbreak.js)

https://github.com/wikimedia/unicodejs

0
ответ дан Ed. 20 August 2018 в 10:15
поделиться

Моей идеей является поиск с кодами, представляющими финские буквы

new RegExp("\\b"+asciiOnly(searchterm), "gi").test(asciiOnly(title))

. Моя первоначальная идея заключалась в использовании plain encodeURI, но знак%, казалось, мешал регулярное выражение.

http://jsfiddle.net/7TsxB/5/

Я написал грубую функцию с использованием encodeURI для кодирования каждого символа с кодом более 128, но удаление его% и добавление «QQ» в начале. Это не лучший маркер, но я не мог заставить не буквенно-цифровые работать.

0
ответ дан Heitor Chang 20 August 2018 в 10:15
поделиться
  • 1
    Это отличная идея, и единственное, что сработало для меня. Вместо QQ вы можете использовать контрольную строку ___, которая немного безопаснее и все еще ascii, а вместо encodeURI вы можете использовать собственные методы escape / unescape javascript, но в противном случае это делает работу , – Mahn 12 October 2015 в 19:53
  • 2
    это нехорошее решение для тех, кто хочет что-то сделать с соответствующей подстрокой – petriq 1 February 2016 в 11:21
  • 3
    – Jānis Elmeris 28 October 2018 в 11:17

этот вопрос старый, но я думаю, что нашел лучшее решение для границы в регулярных выражениях с символами unicode. Используя XRegExp, вы можете реализовать допустимую границу \ b, расширяющую это

XRegExp('(?=^|$|[^\\p{L}])')

, результат имеет длину 4000+, но, похоже, работает довольно эффективно.

Некоторые объяснения: ( ? =) - это просмотр с нулевой длиной, который ищет начальную или конечную границу или небуквенный символ Юникода. Самое главное - это взгляд, потому что \ b ничего не захватывает: это просто правда или ложно.

7
ответ дан max masetti 20 August 2018 в 10:15
поделиться

Кажется, что проблема с Regex и границей слов \b соответствует началу строки с начальным символом из нормального диапазона в 256 байт.

Вместо использования \b попробуйте использовать (?:^|\\s)

var title = "this is simple string with finnish word tämä on ääkköstesti älkää ihmetelkö";
// Does not work
var searchterm = "äl";

// does not work
//var searchterm = "ää";

// Works
//var searchterm = "wi";

if ( new RegExp("(?:^|\\s)"+searchterm, "gi").test(title) ) {
    $("#result").html("Match: ("+searchterm+"): "+title);
} else {
    $("#result").html("nothing found with term: "+searchterm);   
}

Breakdown:

(?: скобки () образуют группу захвата в Regex. Скобка начинается с вопросительного знака, а двоеточие ?: формирует группу, не связанную с захватом. Они просто группируют термины вместе

^ символ каретки совпадает с началом строки

|, бар является оператором «или».

\s соответствует пробелу (отображается как \\s в строке, потому что нам нужно избежать обратного слэша)

) закрывает группу

So вместо использования \b, который соответствует границам слов и не работает для символов Юникода, мы используем группу, не связанную с захватом, которая соответствует началу строки ИЛИ пробела.

36
ответ дан mowwwalker 20 August 2018 в 10:15
поделиться
  • 1
    Это похоже на работу! – user1394520 16 May 2012 в 20:42
  • 2
    & quot; попробуйте это & ​​quot; не является решением. Дайте некоторую информацию о why предлагаемое регулярное выражение. Что делает (?:^|\\s) действительно? Вы вообще не объясняете это решение. – H Dog 4 August 2014 в 21:11
  • 3
    @HDog хороший момент. – mowwwalker 5 August 2014 в 09:39
  • 4
    Это НЕ правильное решение. (?:^|\\s) не является утверждением с нулевой шириной, как \b, и будет потреблять символы из совпадения. Положительный взгляд был бы лучшей идеей ((?=^|\\s)), но будет работать только после матча, так как lookbehind все еще не поддерживается. Кроме того, границы слов - это не просто пробелы и границы строк, а тонна других символов. – Lea Verou 27 February 2017 в 21:57
  • 5
    Есть ли причина не включать $ (конец строки) в регулярное выражение? То есть (?: ^ | \ S | $) – Ron Inbar 7 September 2017 в 13:21

Класс символов \b в JavaScript RegEx действительно полезен только при простой кодировке ASCII. \b - код быстрого доступа для границы между наборами \w и \W или \w и началом или концом строки. Эти наборы символов учитывают только слова ASCII «word», где \w равно [a-zA-Z0-9_], а \W - отрицание этого класса.

Это делает классы символов RegEx в значительной степени бесполезными для работа с любым реальным языком.

\s должен работать для того, что вы хотите сделать, при условии, что условия поиска ограничиваются только пробелами.

16
ответ дан Noah Freitas 20 August 2018 в 10:15
поделиться

Я бы рекомендовал вам использовать XRegExp , когда вам нужно работать с определенным набором символов из Unicode, автор этой библиотеки сопоставил все виды региональных наборов символов, делающих работу с разными языками легче.

5
ответ дан ypid 20 August 2018 в 10:15
поделиться
Другие вопросы по тегам:

Похожие вопросы: