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

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

например. соответствует "через дефис" в:

This sentence contains a hyphena-
ted word.

Ближайшее (непривлекательное) решение:

"h\(-\s*\n\s*\)\?y\(-\s*\n\s*\)\?p\(-\s*\n\s*\)\?h\(-\s*\n\s*\)\?e\(-\s*\n\s*\)\?n\(-\s*\n\s*\)\?a\(-\s*\n\s*\)\?t\(-\s*\n\s*\)\?e\(-\s*\n\s*\)\?d"

Я надеюсь, что какое-нибудь регулярное выражение-foo, более сильное, чем мое, сможет предложить регулярное выражение, которое явно включает искомое слово, т.е. Я бы хотел видеть там слово «через дефис». Я не нашел способа закодировать что-то вроде следующего (что в любом случае было бы ошибочным, поскольку соответствовало бы "hy-ted"):

"{prefix-of:hyphenated}{hyphen/linebreak}{suffix-of:hyphenated}"

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


person user1775138    schedule 25.10.2012    source источник


Ответы (3)


Учитывая, что hy-phen-ated также должен совпадать, я думаю, что это тот случай, когда само по себе регулярное выражение - не правильный путь.

Я бы сделал это (не зная вашего языка, использовал псевдокод):

  1. удалить дефисы и символы новой строки из ввода
  2. сопоставить очищенный ввод с .*hyphenated.*

На всех языках шаг 1 можно выполнить тривиально, и код будет намного более читабельным.

person Bohemian♦    schedule 25.10.2012
comment
Это все еще противоречит требованию OP о невозможности предварительной обработки ввода, хотя сейчас я не могу себе представить, в каком контексте вы можете сопоставить с регулярным выражением, но не можете предварительно обработать вводимый текст. - person famousgarkin; 25.10.2012
comment
Я не хотел загромождать вопрос лишними деталями, но это устаревшее приложение, которое пытается грамотно форматировать и обеспечивает поиск по регулярным выражениям, но нарушает возможность поиска из-за расстановки переносов. - person user1775138; 26.10.2012

Я думаю, это сработает. Если у вас есть много слов для поиска, вы, вероятно, захотите создать сценарий, который сгенерирует для вас шаблон поиска.

[h\-]+\s*[y\-\s]+[p\-\s]+[h\-\s]+[e\-\s]+[n\-\s]+[a\-\s]+[t\-\s]+[e\-\s]+d\b

Я не думаю, что вы упомянули, какой язык вы используете, но я тестировал это с помощью .Net.

Вот простой скрипт на Python, который будет генерировать шаблоны поиска:

# patterngen.py
# Usage:  python patterngen.py <word>
# Example:  python patterngen.py hyphenated

word = sys.argv[1]
pattern = '[' + word[0] + r'\-]+\s*'

for i in range(1,len(word)-1):
    pattern = pattern + r'[' + word[i]
    pattern = pattern + r'\-\s]+'

pattern = pattern + word[-1] + r'\b'
print pattern
person David    schedule 25.10.2012
comment
Это едва ли лучше, чем усилия OP. Я думаю, мы ищем что-то более сложное. - person Bohemian♦; 25.10.2012

Другой способ приблизиться к этому, сразу после летучей мыши, - это "сдвинуть" перенос слов следующим образом:

hyphenated|h(-\s*\n\s*)yphenated|hy(-\s*\n\s*)phenated|hyp(-\s*\n\s*)henated|hyph(-\s*\n\s*)enated|hyphe(-\s*\n\s*)nated|hyphen(-\s*\n\s*)ated|hyphena(-\s*\n\s*)ted|hyphenat(-\s*\n\s*)ed|hyphenate(-\s*\n\s*)d

Читается лучше, но я действительно не знаю, насколько это соответствует производительности вашего исходного шаблона.


Еще одна идея - сначала сузить поиск с помощью шаблона по следующим линиям:

h[hypenatd]{0,9}(-\s*\n*\s)?[hypenatd]{0,9}

а затем сопоставьте результаты этого.

На самом деле, если я не ошибаюсь, если сопоставить с такими группами:

(h[hypenatd]{0,9})(?:-\s*\n*\s)?([hypenatd]{0,9})

то вхождения слова hyphenated - это все совпадения, где псевдокодически:

(match.group1 + match.group2) == "hyphenated"
person famousgarkin    schedule 25.10.2012