2014-10-29 2 views
2

У меня есть требование удалить отступ из пронумерованного абзаца. В настоящее время я делаю это с помощью нескольких регулярных выражений и некоторого кода, но хотел бы выполнить его с одним или несколькими регулярными выражениями. Пункт выглядит следующим образом:Регулярное выражение для удаления отступа

1. THE FIRST LINE OF THE PARAGRAPH 
    ANOTHER LINE IN THE PARAGRAPH 
     AN INDENTED LINE WITHIN THE PARAGRAPH 

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

THE FIRST LINE OF THE PARAGRAPH 
ANOTHER LINE IN THE PARAGRAPH 
    AN INDENTED LINE WITHIN THE PARAGRAPH 

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

(\A *\d+\. *|^ {0,5}) 

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

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

ответ

1

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

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

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

re.sub(r"^([\d\. ]+)(.*)$", 
    lambda m: re.sub("^" + " "*len(m.group(1)), 
        "", 
        m.group(2), 
        flags=re.MULTILINE), 
    paragraph, 
    flags=re.MULTILINE|re.DOTALL) 

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

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

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

0

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

Попробуйте это:

^((?:\d+\.)? +) 

использовать что-то вроде http://www.regexr.com/, чтобы проверить это.

+0

Выражение в правой части | соответствует от 0 до 9 пробелов, начинающихся в начале строки. Думаю, вы не видели пространства? Ваше выражение удаляет все пространство перед каждой строкой, но не сохраняет отступ третьей строки. Спасибо за вашу помощь. – user3565980

+0

Я просто понял, что мое решение, использующее буквальное значение «9», не было тем, что я намеревался - это должно было быть «4». Я исправил это для ясности. – user3565980

+0

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

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