2012-03-01 3 views
3

Я использую Caliber для преобразования PDF в MOBI, но у него есть проблемы с интерпретацией пространственно-вдавленных блоков кода. Блоки содержат много пространств, но в большом количестве. Некоторые строки имеют отступы на 31 пробел.Как заменить определенное количество пробелов с помощью регулярного выражения?

Caliber позволяет выполнять 3 регулярных выражения для поиска и замены в книге до ее преобразования.

Это то, что я пробовал.

\n(*) (*)([a-zA-Z{};\*\/\(\)&#0-9]) 

Заменить:

\n\1 \2\3 

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

Я также попытался ленивые версии первой группы и т.д.

Является ли это один из тех случаев, когда регулярные выражения являются недостаточными? Я думаю, что этот механизм регулярных выражений является стандартом python.

ответ

2

Если это Perl можно заменить (\G|\n)  с $1&nbsp;, и если бы это было регулярное выражение двигатель, который позволил Ограниченные ширины lookbehinds (вместо фиксированной ширины lookbehinds, таких как Python), вы можете заменить (?<=\n {0,30})  на &nbsp;; но как бы то ни было, единственный способ, которым я могу думать, это заменить что-то вроде ((?<=\n)|(?<=\n)|(?<=\n {2})|(?<=\n {3})|(?<=\n {4})|(?<=\n {5})|...|(?<=\n {30}))  на &nbsp;. , , и я подозреваю, что в этот момент вы достигнете предела в отношении того, как долго Caliber допускает входное регулярное выражение. : -/

Другой вариант - использовать совершенно другой подход и заменить    (два пробела) на &nbsp;  (свободное пространство без пробелов + регулярное пространство), не мешая ему ограничивать его до начала строки. Я предполагаю, что это удовлетворит ваши потребности?

+0

Теперь это выглядит лучше. Я никогда не получу идеальный результат, но это определенно читаемо, спасибо :-) – Steinbitglis

+0

@Steinbitglis: Добро пожаловать. Я рад слышать это. :-) – ruakh

+0

Быстрые и грязные хаки на помощь! –

1

\ s {31} будет соответствовать ровно 31 белых пространств, \ s {14,31} 14 до 31

+0

И что бы я заменить это? – Steinbitglis

1

Любые причины не просто заменять ВСЕ пробелы неразрывными пробелами? (r/ /&nbsp;/.)

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


Для удовольствия, моя попытка в Python:

>>> eight_spaces = "  hello world!" 
>>> re.sub(r"^(|(?:&nbsp;)*)\s",r"\1&nbsp;",eight_spaces) 
'&nbsp;  hello world!' 

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

Обратите внимание на чередование (?:&nbsp;)* с пустой строкой, (|(?:&nbsp;)*), так что группа захвата \1 всегда захватывает что-то (даже пустую строку.)

+0

Я еще не тестировал, но я подозреваю, что текст не будет течь, как должно. В конце концов, это не разрывное пространство. – Steinbitglis

+0

Если я правильно помню, неиспользуемое пространство по-прежнему будет проходить через линии - разница в том, что соседние ' ' не будут уплотняться в одно пространство. Поправьте меня если я ошибаюсь. –

+0

@Steinbitglis Ах, вы правы - неразрывное пространство действительно «не-линейное». ;) –