Удалять жесткие разрывы строк из текста с помощью Ruby - PullRequest
5 голосов
/ 29 января 2011

У меня есть текст с жесткими переносами строк, например:

This should all be on one line 
since it's one sentence.

This is a new paragraph that
should be separate.

Я хочу удалить одиночные переводы строк, но сохранить двойные переводы строк, чтобы это выглядело так:

This should all be on one line since it's one sentence.

This is a new paragraph that should be separate.

Есть ли одно регулярное выражение, чтобы сделать это?(или каким-то простым способом)

Пока это мое единственное решение, которое работает, но кажется хакерским.

txt = txt.gsub(/(\r\n|\n|\r)/,'[[[NEWLINE]]]')
txt = txt.gsub('[[[NEWLINE]]][[[NEWLINE]]]', "\n\n")
txt = txt.gsub('[[[NEWLINE]]]', " ")

Ответы [ 5 ]

9 голосов
/ 29 января 2011

Заменить все новые строки, за которыми не следует или не предшествует новая строка:

text = <<END
This should all be on one line
since it's one sentence.

This is a new paragraph that
should be separate.
END

p text.gsub /(?<!\n)\n(?!\n)/, ' '
#=> "This should all be on one line since it's one sentence.\n\nThis is a new paragraph that should be separate. "

Или, для Ruby 1.8 без поиска:

txt.gsub! /([^\n])\n([^\n])/, '\1 \2'
4 голосов
/ 29 января 2011
text.gsub!(/(\S)[^\S\n]*\n[^\S\n]*(\S)/, '\1 \2')

Две группы (\S) служат тем же целям, что и обходные пути ((?<!\s)(?<!^) и (?!\s)(?!$)) в регулярных выражениях @ sln:

  • они подтверждают, что перевод строки действительно находится вв середине предложения и
  • они гарантируют, что часть [^\S\n]*\n[^\S\n]* потребляет любое другое пустое пространство, окружающее перевод строки, что позволяет нам нормализовать его до одного пробела.

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

1 голос
/ 29 января 2011

Форматирование (отключение переноса слов) - это нечто большее, чем вы думаете.
Если вывод является результатом операции форматирования, тогда вам следует воспользоваться
этими правилами для обратного инжиниринга оригинала.

Например, у вас есть тест

This should all be on one line
since it's one sentence.

This is a new paragraph that
should be separate.

ЕслиВы удалили только одиночные новые строки, это будет выглядеть так:

This should all be on one line since it's one sentence.
This is a new paragraph thatshould be separate.

Кроме того, будет потеряно другое форматирование, такое как преднамеренные новые строки, поэтому что-то вроде:

This is Chapter 1
   Section a 
   Section b

Превращается в

This is Chapter 1   Section a   Section b

Найти новую строку очень просто /(?<!\n)\n(?!\n)/
но чем ее заменить.

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

Есть 4 пути.

Удалить перевод строки, сохранить окружающее форматирование
$text =~ s/(?<!\s)([^\S\n]*)\n([^\S\n]*)(?!\s)/$1$2/g;
Удалить перевод строки и форматирование, подставитьпробел
$text =~ s/(?<!\s)[^\S\n]*\n[^\S\n]*(?!\s)/ /g;

То же, что и выше, но игнорировать символ новой строки в начале или конце строки

$text =~ s/(?<!\s)(?<!^)[^\S\n]*\n[^\S\n]*(?!$|\s)/ /g;
$text =~ s/(?<!\s)(?<!^)([^\S\n]*)\n([^\S\n]*)(?!$|\s)/$1$2/g;

Пример разбивки регулярного выражения(это минимум, необходимый только для выделения одной новой строки):

(?<!\s)      # Not a whitespace behind us (text,number,punct, etc..)
[^\S\n]*     # 0 or more whitespaces, but no newlines
\n           # a newline we want to remove
[^\S\n]*     # 0 or more whitespaces, but no newlines
(?!\s)/      # Not a whitespace in front of us (text,number,punct, etc..)
0 голосов
/ 29 января 2011
$ ruby -00 -pne 'BEGIN{$\="\n\n"};$_.gsub!(/\n+/,"\0")' file
This should all be on one line since it's one sentence.

This is a new paragraph thatshould be separate.
0 голосов
/ 29 января 2011

Ну, вот что:

s.gsub /([^\n])\n([^\n])/, '\1 \2'

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

s.gsub(/([^\n])\n([^\n])/, '\1 \2').strip
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...