IntelliJ: Регулярное выражение для объединения нескольких строк в одну строку CSV? - PullRequest
1 голос
/ 21 января 2020

Иногда мне нужно объединить несколько строк данных в одну строку, и в этом случае, в частности, в виде значений через запятую в одной строке:

input: (строки вставлены в некоторые Android Studio вкладка редактора)

Rush
IQ
Saga
Yes

желаемый вывод:

'Rush','IQ','Saga','Yes'

Правка> Найти> Заменить Я получил этот шаблон регулярного выражения, чтобы соответствовать символу новой строки (\ n) с целью устранить его:

search: ^(.*)$\n
replace: '$1',
[x] Regex

, но выдает этот нежелательный вывод:

'Rush',IQ
'Saga',Yes  

, потому что после удаления новой строки следующая строка уже примыкает, поэтому она пропускается ... так мы получаем поведение "каждая вторая линия".

Ответы [ 3 ]

0 голосов
/ 22 января 2020

Шаг 1: Чтобы объединить строки, используйте

(.+)(?:\R|\z)

Замените на '$1',.

Шаблон (.+)(?:\R|\z) соответствует любым 1+ символам, кроме символы разрыва строки могут быть как можно больше (.+) и заносятся в группу 1, а (?:\R|\z) соответствует либо последовательности разрыва строки (\R), либо (|) на самом конце строки (\z) .

Шаг 2 : постобработка путем повторного ввода ,$ с пустой строкой. Этот шаблон соответствует , в конце строки.

0 голосов
/ 23 января 2020

Иногда мне нужно объединить несколько строк данных в одну строку, и в этом случае, в частности, в виде значений через запятую в одной строке:

Регулярное выражение может не быть лучшее решение для этого.

Библиотека CSV

Существует несколько библиотек с разделителями-запятыми (CSV) , доступных для быстрой работы.

Библиотеки решат конкретную проблему, которую вы можете не заметить при написании собственного кода: некоторые из ваших строк ввода имеют знак , заключенный в одинарные кавычки, в своем содержимом . Такие случаи нужно избегать. Цитирование RF C 4180 раздел 2.7:

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

  "aaa","b""bb","ccc"

Вот пример использования библиотеки Apache Commons CSV .

Мы используем лямбда-синтаксис с Scanner, чтобы получить Iterable строк текста из вашего ввода.

Мы указываем использование одиночной кавычки, как вам нужно, а не значение по умолчанию двойной цитата в стандартном CSV.

Мы используем синтаксис try-with-resources для автоматического закрытия объекта CSVPrinter, независимо от того, выполняется наш код успешно или выдает исключение.

String input = "Rush\n" +
        "IQ\n" +
        "Saga\n" +
        "Yes";

Iterable < String > iterable = ( ) -> new Scanner( input ).useDelimiter( "\n" );  // Lambda syntax to get a `Iterable` of lines from a `String`. 

CSVFormat format =
        CSVFormat
                .RFC4180
                .withQuoteMode( QuoteMode.ALL )
                .withQuote( '\'' );
StringBuilder stringBuilder = new StringBuilder();
try (
        CSVPrinter printer = new CSVPrinter( stringBuilder , format ) ;
)
{
    printer.printRecord( iterable );
}
catch ( IOException e )
{
    e.printStackTrace();
}

String output = stringBuilder.toString();

System.out.println( "output: " + output );

При запуске:

вывод: 'Ru sh', 'IQ', 'Saga', 'Yes'

Мы можем сократить этот код.

try (
        CSVPrinter printer = new CSVPrinter( new StringBuilder() , CSVFormat.RFC4180.withQuoteMode( QuoteMode.ALL ).withQuote( '\'' ) ) ;
)
{
    printer.printRecord( ( Iterable < String > ) ( ) -> new Scanner( input ).useDelimiter( "\n" ) );
    System.out.println( printer.getOut().toString() );  // Or: `return printer.getOut()` returning an `Appendable` object. 
}
catch ( IOException e )
{
    e.printStackTrace();
}

Не то чтобы это было особенно укорочено. Лично я бы использовал более длинную версию, заключенную в метод в служебном классе. Вот так:

public String enquoteLines( String input ) {
    String output = "";
    Iterable < String > iterable = ( ) -> new Scanner( input ).useDelimiter( "\n" );  // Lambda syntax to get a `Iterable` of lines from a `String`.

    CSVFormat format =
            CSVFormat
                    .RFC4180
                    .withQuoteMode( QuoteMode.ALL )
                    .withQuote( '\'' );
    StringBuilder stringBuilder = new StringBuilder();
    try (
            CSVPrinter printer = new CSVPrinter( stringBuilder , format ) ;
    )
    {
        printer.printRecord( iterable );
        output = printer.getOut().toString();
    }
    catch ( IOException e )
    {
        e.printStackTrace();
    }

    return output;
}

Называя его:

String input = "Rush\n" +
        "IQ\n" +
        "Saga\n" +
        "Oui";

String output = this.enquoteLines( input );
0 голосов
/ 21 января 2020

Самый быстрый и простой способ, который я мог придумать, это заменить \n на ',', а затем вручную обернуть всю строку в кавычки:

Результатом первой замены будет:

Rush','IQ','Saga','Yes

А потом просто вручную добавьте первую и последнюю цитату.

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