Регулярное выражение для соответствия частичных слов (JavaScript) - PullRequest
6 голосов
/ 16 апреля 2010

Я хотел бы создать регулярное выражение без учета регистра (для JavaScript), которое соответствует названиям улиц, даже если каждое слово было сокращено. Например:

n унив av должен соответствовать N унив ersity Av e

Кинг-буль должен соответствовать Мартину Лютеру Кинг мл. Буль д

ne 9th должно соответствовать обоим NE 9th St и 9th St NE

Бонусные баллы (JK) для регулярного выражения "замена", которое оборачивает сопоставленный текст тегами <b>.

Ответы [ 4 ]

11 голосов
/ 16 апреля 2010

Вы получили:

"n univ av"

Вы хотите:

"\bn.*\buniv.*\bav.*"

Итак, вы делаете:

var regex = new RegExp("n univ av".replace(/(\S+)/g, function(s) { return "\\b" + s + ".*" }).replace(/\s+/g, ''), "gi");

Вуаля!

Но я еще не закончил, мне нужны мои бонусные очки. Поэтому мы изменим шаблон на:

var regex = new RegExp("n univ av".replace(/(\S+)/g, function(s) { return "\\b(" + s + ")(.*)" }).replace(/\s+/g, ''), "gi");

А потом:

var matches = regex.exec("N University Ave");

Теперь мы получили:

  • соответствует [0] => всему выражению (бесполезно)
  • совпадений [чёт] => один из наших совпадений
  • соответствует [нечетное] => дополнительный текст не в исходной строке соответствия

Итак, мы можем написать:

var result = '';
for (var i=1; i < matches.length; i++)
{
  if (i % 2 == 1)
    result += '<b>' + matches[i] + '</b>';
  else
    result += matches[i];
}
2 голосов
/ 16 апреля 2010
function highlightPartial(subject, search) {
  var special = /([?!.\\|{}\[\]])/g;
  var spaces  = /^\s+|\s+/g;
  var parts   = search.split(" ").map(function(s) { 
    return "\b" + s.replace(spaces, "").replace(special, "\\$1");
  });
  var re = new RegExp("(" + parts.join("|") + ")", "gi");
  subject = subject.replace(re, function(match, text) {
    return "<b>" + text + "</b>";
  });
  return subject;
}

var result = highlightPartial("N University Ave", "n univ av");
// ==> "<b>N</b> <b>Univ</b>ersity <b>Av</b>e"

Примечание: эта реализация не учитывает порядок соответствия, поэтому:

var result = highlightPartial("N University Ave", "av univ n");
// ==> "<b>N</b> <b>Univ</b>ersity <b>Av</b>e"

Если это проблема, потребуется более сложный последовательный подход, чего я здесь избежал, используя функцию обратного вызова replace().

1 голос
/ 16 апреля 2010

Simple:

var pattern = "n univ av".replace(/\s+/, "|");
var rx      = new RegExp(pattern, "gi");
var matches = rx.Matches("N University Ave");

Или что-то в этом роде.

0 голосов
/ 16 апреля 2010

Если это ваши условия поиска:

  1. н унив ав
  2. Кинг бул
  3. ne 9th

Похоже, ваш алгоритм должен выглядеть примерно так

  1. разделить поиск по пробелам (результаты в массиве поисковых терминов) input.split(/\s+/)
  2. попытка сопоставить каждый термин в пределах вашего ввода. /term/i
  3. для каждого соответствующего ввода, замените каждый термин на термин, заключенный в теги <b>. input.replace(/(term)/gi, "<b>\$1</b>")

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...