2010-02-09 6 views
2

Я хочу многострочные строки в java, поэтому я ищу простой препроцессор для преобразования многострочных линий C-стиля в отдельные строки с буквальным «\ n».Какой самый яркий способ заменить обратную косую черту с n?

До:

System.out.println("convert trailing backslashes\ 
this is on another line\ 
\ 
\ 
above are two blank lines\ 
But don't convert non-trailing backslashes, like: \"\t\" and \'\\\'"); 

После:

 System.out.println("convert trailing backslashes\nthis is on another line\n\n\nabove are two blank lines\nBut don't convert non-trailing backslashes, like: \"\t\" and \'\\\'"); 

Я думал sed бы сделать это хорошо, но СЭД является построчным, поэтому замена «\» и символ новой строки, которая следует за ней (эффективно соединяющий две линии) не очень естественно в sed. Я приспособил sredden79's oneliner к следующему - он работает, это умное, но это не ясно:

sed ':a { $!N; s/\\\n/\\n/; ta }' 

Заменитель имеет escaped literal backslash, newline с escaped literal backslash, n. :a - это метка, а ta - метка goto, если замена найдена совпадением; $ означает последнюю строку, а $! - противоположность (т. Е. Все строки, кроме последней). N означает добавить следующую строку в шаблоне пространства (таким образом делая \n характер видимым.)

EDIT здесь изменение, чтобы компилятор номеров строк ошибок и т.д. точно: она превращает каждую расширенную линию в "..."+\n (и обрабатывает первые и последние строки Строка корректно):

sed ':a { $!N; s/\\\n/\\n"+\n"/; ta }' 

дает:

System.out.println("convert trailing backslashes\n"+ 
"this is on another line\n"+ 
"\n"+ 
"\n"+ 
"above are two blank lines\n"+ 
"But don't convert non-trailing backslashes, like: \"\t\" and \'\\\'"); 

EDIT На самом деле было бы лучше иметь многострочный стиль Perl/Python, где он начинается и заканчивается специальным кодом в одной строке («,» для python, я думаю).

Есть ли более простой, более чистый, понятный способ (возможно, не использование sed)?

+3

Если вы сделаете это, вы будете убивать поддержку своих инструментов. Внезапно никакая среда IDE не будет правильно подсвечивать синтаксис, отладчики будут показывать разные номера строк, чем ваш (исходный) исходный файл ... Помните, что компилятор (во время компиляции) объединяет литеральные строки, объединенные с '+', поэтому просто закрывая строка, написание '+' и открытие ее на следующей строке устраняет препроцессор и сохраняет поддержку инструмента. FWIW. –

ответ

3

Perl-один-лайнер:

perl -0777 -pe 's/\\\n/\\n/g' 

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

Если вы используете редактор, который поддерживает фильтрацию, как VI или Emacs, просто отфильтровать текст с помощью команды выше, и вы сделали:

Если вы используете Windows, и придется беспокоиться о \r :

C:\> perl -0777 -pe "s/\\\r?\n/\\n/g" 

хотя я думаю, что win32 Perl обрабатывает \r сам так что это может оказаться ненужным.

Опция -0777 является специальным случаем опции -0 (это нуль), которая определяет разделитель строк или записей. В этом случае это означает, что мы не хотим, чтобы разделитель так читал весь файл в виде одной строки.

Опция -pe представляет собой сочетание -p (технологической линии за линией и печати результата) и -e (следующий аргумент (строка) программа для выполнения)

5

Есть ли более простой, понятный и понятный способ.

Забудьте пре-процессор, жить с ограничением, жалуются на него (так, что он будет, возможно, будет исправлена ​​в Java 7 или 8), и use an IDE to ease the pain.

Других альтернатив (слишком хлопотно, я полагаю, но все же лучше, чем возиться с процессом компиляции):

  • использовать JVM на основе языка, который не поддерживает здесь докторант
  • экстернализовать строку в ресурс файл
+0

+1 используйте IDE/emacs –

+0

Спасибо 1. Идея IDE классная, но не помогает при редактировании (это боль для редактирования, добавления, перемещения между строками многострочных конкатенированных строк - вот что я использовал) , 2. Внешнее использование в файле ресурсов - это то, что я делаю сейчас, но я думаю, что проще и удобнее иметь его вместе с исходным кодом, к которому он относится. 3. Весь новый JVM-язык просто для решения этой проблемы кажется неприятным, но ... он уже будет отлажен и т. Д., И будет иметь поддержку инструмента, подсветку синтаксиса и т. Д., Поэтому ваша идея имеет интригующую элегантность! Конечно, сценарий sed можно рассматривать как «язык JVM». – 13ren

1

Perl-скрипт к тому, что вы просили.

while (<>) { 
    chomp; 
    print $_; 
    if (/\\$/) { 
     print "n"; 
    } else { 
     print "\n"; 
    } 
} 
0
sed 's/\x5c\x5c$/\x22\x5c\x5cn\x22/' 

шестигранных для обратной косой черты и двойная кавычка - \ x5c и \ x22 соответственно - ее нужно экранировать, так что \ x5c удваивается, а $ anchors - до конца строки.

Обновлено снова на OP комментарий:

sed "{:a;N;\$!b a};s/\x5c\x5c\n/\x5c\x5cn/g" 

: а создает ярлык и N присоединяет строку в шаблоне пространства, ба ветви назад к метке: а кроме случаев, когда его последняя строка $ !;

После его загрузки - однострочная подстановка заменяет все вхождения строки новой строки \ n литералом '\ n', используя шестнадцатеричный код ascii \ x5c для обратного слэша.

+0

Это не объединяет строки (и добавляет кавычки, которые не нужны). Попробуйте на примере, приведенном в вопросе, и сравните результат, чтобы понять, что я имею в виду. – 13ren

+0

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

+0

Это похоже на решение sed, которое уже находится в самом вопросе.Кроме того, вы можете просто скрыть обратную косую черту, которая более читаема, чем hex. Но вы, кажется, знаете свой путь вокруг sed - может быть, вы можете придумать более ясную версию (это был реальный вопрос). Но я не уверен, что есть один, просто из-за необходимости присоединяться к строкам (или глотать их в пространстве шаблонов, когда вы его описываете). Может быть, просто сделайте это в двухэтапном конвейере, первый присоединится ко всему, второй - к фактическому матчу? В любом случае, прочитайте весь вопрос и получите его! – 13ren

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

  • Нет связанных вопросов^_^