Выражение регулярного выражения, использующее границу слова для сопоставления буквенно-цифровых и не буквенно-цифровых символов в JavaScript - PullRequest
4 голосов
/ 18 ноября 2010

Я пытаюсь выделить набор ключевых слов с помощью JavaScript и регулярных выражений, я столкнулся с одной проблемой, мое ключевое слово может содержать буквенные и специальные символы, как в @text #number и т. Д. Я использую границу слова для сопоставления и замены всего словаа не частичное слово (содержащееся в другом слове).

var pattern = new regex('\b '( + keyword +')\b',gi);

Здесь это выражение соответствует целым ключевым словам и выделяет их, однако в случае, если какое-либо ключевое слово, например "число:", не выделяется.

Мне известно, что \bword\b соответствует границе слова, а специальные символы не являются буквенно-цифровыми символами, следовательно, не соответствуют вышеприведенному выражению.Можете ли вы дать мне знать, какое выражение регулярного выражения я могу использовать для достижения вышеизложенного.

== Обновление ==

Для вышеизложенного я попробовал предложение Тима Пицкера для приведенного нижеregex,

expr: (?:^|\\b|\\s)(" + keyword + ")(?:$|\\b|\\s)

Вышеприведенное, кажется, работает для того, чтобы получить совпадение для всего слова с буквенно-цифровыми и не буквенно-цифровыми символами, однако всякий раз, когда ключевое слово имеет последовательный тег html до или после ключевого слова без пробела,это ключевое слово не выделяется (например, номер социального страхования * номер:
*). Я использовал следующее регулярное выражение, но оно заменяет тег html, предшествующий ключевому слову

* 1021.*

Здесь для ключевого слова число: с < br > (преднамеренно добавлено пространство для тега br, чтобы избежать интерпретации тега браузером), следующее за ним без пробела между ними, выделяется ключевым словом.

Можете ли вы предложить выражение, которое будет игнорировать последовательный тег html для всего слова с буквенно-цифровыми и не буквенно-цифровыми символами.

Ответы [ 6 ]

2 голосов
/ 18 ноября 2010

ОК, поэтому у вас есть две проблемы: JavaScript не поддерживает вид сзади, а \b находит только границы между буквенно-цифровыми и не буквенно-цифровыми символами.

Первый вопрос: что именно делает составляют границы слов для ваших ключевых слов?Я предполагаю, что это должна быть либо граница \b, либо пробел.Если это так, вы могли бы искать

"(?:^|\\b|\\s)(" + keyword + ")(?:$|\\b|\\s)"

Конечно, пробельные символы вокруг ключевых слов, таких как @number#, также стали бы частью соответствия, но, возможно, их выделение не является такой проблемой.В других случаях, т. Е. Если существует фактическая граница слова, которая может совпадать, пробелы не будут частью соответствия, поэтому в большинстве случаев она должна работать нормально.

Фактическое слово, которое вас интересуетin будет иметь обратную ссылку # 1, так что если вы можете выделить это отдельно, даже лучше.

РЕДАКТИРОВАТЬ: Если после / перед ключевым словом могут появляться другие символы, кроме пробела, то я думаю, что единственное, что вы можете сделать (если вы застряли с JavaScript) это:

  1. Проверьте, начинается ли ваше ключевое слово с символа alnum.
  2. Если это так, добавьте \b к своему регулярному выражению.
  3. Проверьте, заканчивается ли ваше ключевое слово буквенным символом.
  4. Если это так, добавьте \b к своему регулярному выражению.

Итак, для keyword используйте \bkeyword\b;для number: используйте \bnumber:;для @twitter используйте @twitter\b.

1 голос
/ 18 ноября 2010

Нам нужно найти подстроку, которая имеет символ пробела с обеих сторон .Если бы JavaScript поддерживал внешний вид, это выглядело бы следующим образом:

var re = new RegExp('(?<!\\S)' + keyword + '(?!\\S)', 'gi');

Это не сработает (но будет в Perl и других языках сценариев).Вместо этого нам нужно включить начальный символ пробела (или начало строки) в качестве начальной части матча (и при желании захватить то, что мы действительно ищем в $ 1):

var re = new RegExp('(?:^|\\s)(' + keyword + ')(?!\\S)', 'gi');

Просто учтите, что реальное место , где начинается любое совпадение, будет через один символ после , что возвращается свойством .index, возвращаемым re.exec(string), и что если вы обращаетесь киз соответствующей строки вам нужно либо удалить первый символ с помощью .slice(1), либо просто получить доступ к захваченному.

0 голосов
/ 10 сентября 2011

Попробуйте, это должно работать ...

var pattern = new regex(@"\b"+Regex.escape(keyword)+@"\b",gi);
0 голосов
/ 18 ноября 2010

Как правильно указывает Тим, \b - это хитрые вещи, которые работают не так, как люди думают, что они работают. Прочитайте этот ответ для получения более подробной информации об этом вопросе и о том, что вы можете с этим сделать.

Вкратце, это граница слева:

(?(?=\w)(?<!\w)|(?<!\W))

и это граница справа:

(?(?<=\w)(?!\w)|(?!\W))

Люди всегда думают, что есть пробелы, но их нет. Однако теперь, когда вы знаете реальные определения, их легко встроить в них. Можно поменять местами \w и \W на \s и \S в двух вышеприведенных схемах. Или можно добавить в пробел осведомленность к остальным блокам.

0 голосов
/ 18 ноября 2010

Взгляд вперед и назад - ваш ответ: "(?=<[\s^])" + keyword + "(?=[\s$])".Биты в скобках не включены в соответствие, поэтому включайте любые символы, которые не разрешены в ключевых словах там.

0 голосов
/ 18 ноября 2010

Может быть, вы пытаетесь сделать

'\b\W*(' + keyword + ')\W*\b'
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...