2010-11-29 3 views
5

У меня есть некорректно прокомментированный старый код здесь, который использует boost::regex::perl. Мне было интересно об одной конкретной конструкции раньше, но поскольку код работал (более или менее), я не хотел касаться его.boost :: regex - bb?

Теперь я есть прикоснуться к ней, по техническим причинам (точнее, текущие версии Boost, больше не принимает конструкцию), так что я должен понять, что это делает - или, скорее, был предназначен делать.

Соответствующая часть регулярного выражения:

(?<!(\bb\s|\bb|^[a-z]\s|^[a-z])) 

Кусок, который дает мне головные боли является \bb. Я знаю \b, но я не мог найти упоминания о \bb, и ища литерал 'b' здесь не имеет смысла. Есть \bb какая-то специальная недокументированная функция, или я должен считать эту опечатку?

+2

Не могли бы вы не просто попробовать, если `\ bb` соответствует«б» (а не «а»), чтобы проверить, действительно ли оно делает что-либо иное, кроме границы слова, а затем «b»? – Jens 2010-11-29 14:57:01

+0

Ну, проблема - как и со всем бездокументарным кодом - заключается в том, что то, что он * делает *, может не соответствовать действительности, что было * предназначено для выполнения. Мне пришлось бы протестировать его против старой версии (1.34.1) и текущей версии Boost, и * все еще нужно было бы догадаться о намерении автора ... – DevSolar 2010-11-29 15:33:44

ответ

3

(\bb\s|\bb|^[a-z]\s|^[a-z]) соответствует b, если он не предшествует другому символа слова или любой строчной буквы, если это в начале строки. В любом случае за буквой может следовать символ пробела. (Это может соответствовать прописным буквам тоже, если режим не чувствителен к регистру установлен, и ^ может также соответствовать началу строки, если многострочному режим.)

Но внутри назад ', что даже не должно скомпилирована. В некоторых вариантах lookbehind может содержать несколько альтернатив с разными фиксированными длинами, но чередование должно быть на верхнем уровне в lookbehind. То есть (?<=abc|xy|12345) будет работать, но (?<=(abc|xy|12345)) не будет.Таким образом, ваше регулярное выражение не будет работать даже в тех, что есть, но документы Boost просто говорят, что выражение lookbehind должно быть фиксированным.

Если вам действительно нужно учитывать все четыре возможности соответствующих этим регулярным выражением, я предлагаю вам разделить на два назад ':

(?<!\bb|^[a-z])(?<!(?:\bb|^[a-z])\s) 
4

Как Boost представляется механизм регулярных выражений для C++, а один из режимов совместимости является совместимость Perl - если это является «Perl-совместимый» выражение, чем второе «B» может только быть буквальный.

Это допустимое выражение, в значительной степени особый случай для слов, начинающихся с 'b'.

Кажется, решающим фактором является то, что это библиотека C++, и что она должна давать среды, которые не являются perl, perl-совместимыми регулярными выражениями. Таким образом, моя оригинальная мысль о том, что perl может интерпретировать выражение (например, overload::constant), является недопустимой. Тем не менее, это все равно стоит упомянуть только для разъяснений, независимо от того, насколько нецелесообразно было бы подстроить выражение, означающее «слово, начинающееся с« b ».

Единственное предостережение к этой идее, что возможно подталкивания вне выполняет Perl на это собственные выражениях и кто-то будет использовать подпиточный двигатель в среду Perl, то все ставки выключены в отношении того, что может иметь было обозначено как специальное выражение. Это всего лишь один удар, учитывая грамматику, где «!!!» имел в виду что-то особенное в начале слов, вы можете контрейлерных на установленном значении, как это (не рекомендуется!)

s/\\bb\b/(?:!!!(\\p{Alpha})|\\bb)/ 

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

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