2015-07-16 2 views
4

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

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

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

var regexPattern = string.Format("\\b({0})\\b", keyphrase); 

Когда ключевая фраза является несколько слов (содержит один или несколько пробелов), я затем обновив выражение для замены любого из этих пространств с шаблоном:

regexPattern = regexPattern.Replace(" ", ".*"); 

Есть несколько сценариев, в которых это не ведут себя, как мне нужно это.

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

2) В сценарии, где моя ключевая фраза состоит из нескольких слов (содержит 1 или более пробелов), я хотел бы разрешить до определенного максимального расстояния/длины между каждым из слов, которые формируют мою ключевую фразу.

например. Если моя ключевая фраза является:

for sale 

... и текст, который я соответствие с это

I have a bike for sale. 

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

bike for sale 

Однако, если было больше расстояния между словами, чем ключевой фразой 5 символов, я бы не хотел, чтобы соответствовать.

Кроме того, это «расстояние» не должно быть ограничено количество пробелов, которые происходят между ключевую фразу словами, как я хотел бы также следующее, чтобы соответствовать, например:

I have a bike for _.,1sale. 

Наконец, это, вероятно, что в некоторых случаях ключевая фраза, которую я ищу, может появляться более одного раза, и, когда выполняются вышеуказанные условия, мне нужно, чтобы оба они были согласованы:

eg

I have a bike for _.,1sale. I've also got a laptop for sale! 

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

+0

Вторая проблема легко адресована предельным квантором '. {1,5}' (от 1 до 5 вхождений любых символов, кроме новой строки). Но если граница слов предотвращает совпадение ключевого слова, просто удаляйте границы слов или используйте интеллектуальный метод, который будет «знать», где их добавлять, а где нет. Если вы просто хотите, чтобы он соответствовал цифрам и '_', вы можете проверить' string.Format ("(? <= \\ P {L} | ^) ({0}) (? = \\ P { L} | $) ", keyphrase)' –

ответ

2

Я думаю, вы можете использовать следующий код для решения 2 вопроса:

var regexPattern = string.Format("(?<!\\p{{L}}){0}(?!\\p{{L}})", keyphrase); 
// or 
// var regexPattern = string.Format("(?<=\\P{{L}}|^){0}(?=\\P{{L}}|$)", keyphrase); 
regexPattern = regexPattern.Replace(" ", ".{0,5}"); 

Регулярное выражение будет выглядеть

(?<!\p{L})key.{0,5}word(?!\p{L}) 

или

(?<=\P{L}|^)key.{0,5}word(?=\P{L}|$) 

Вот demo 1/demo 2

вида, что если вы хотите, чтобы также соответствовать внутренним словоразделам таким же образом, использовать

regexPattern = regexPattern.Replace(" ", "(?=\\P{L}).{0,5}(?<=\\P{L})"); 

Regex будет

(?<!\p{L})key(?=\P{L}).{0,5}(?<=\P{L})word(?!\p{L}) 

или

(?<=\P{L}|^)key(?=\P{L}).{0,5}(?<=\P{L})word(?=\P{L}|$) 

См demo, это исключит случаи, когда 2 слова не будут совпадать, если они склеены.

+1

Отлично, первый пример, который вы предоставили, работает точно так, как мне нужно. Спасибо за такой полный ответ и демо! – marcusstarnes

+1

Просто для полноты я обнаружил, что мне нужно было избежать фигурных скобок для {L} в строке. Линия флага else it error'd, поэтому она стала: var regexPattern = string.Format ("(? <= \\ P {{L}} | ^) {0} (? = \\ P {{L}} | $) ", keyphrase); – marcusstarnes

+0

Я думаю, что объединение строк лучше в этом случае, так как мы избегаем экранирования '{' и '}'. Btw, '(? <= \ P {L} | ^)' эквивалентно '(? nhahtdh

Смежные вопросы