Переформатировать строку списка с пробелами

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

Предположим, что файл примера выглядит следующим образом:

List(UT_LVL_17_CD, UT_LVL_20_CD, 2018 1Q, 2018 2Q, 2018 3Q, 2018 4Q, 2018 FY)
List(UT_LVL_17_CD,UT_LVL_20_CD,2018 1Q,2018 2Q,018 3Q,2018 4Q,2018 FY)
List( UT_LVL_17_CD,    UT_LVL_20_CD,2018 1Q,2018 2Q, 2018 3Q, 2018 4Q, 2018 FY )

Для всех трех вышеуказанных комбинаций вывод должен быть

List("UT_LVL_17_CD", "UT_LVL_20_CD", "2018 1Q", "2018 2Q", "2018 3Q", "2018 4Q", "2018 FY")

обратите внимание, что пробелы в начале, конце или между элементами допустимы.

List(  "UT_LVL_17_CD", "UT_LVL_20_CD", "2018 1Q", "2018 2Q", "2018 3Q", "2018 4Q",    "2018 FY" )

но не в пределах строкового значения, как показано ниже

"     UT_LVL_17_CD"
"UT_LVL_20_CD   ",

пробелы, которые уже есть в каждом элементе, должны быть сохранены "2018 4Q"

Я пытаюсь что-то вроде ниже, но не могу получить правильный результат.

$ perl -pe ' s/(?<=\()|(?=,)|(?=\))/\"/sg ' list.txt
List("UT_LVL_17_CD", UT_LVL_20_CD", 2018 1Q", 2018 2Q", 2018 3Q", 2018 4Q", 2018 FY")
List("UT_LVL_17_CD",UT_LVL_20_CD",2018 1Q",2018 2Q",018 3Q",2018 4Q",2018 FY")
List(" UT_LVL_17_CD",    UT_LVL_20_CD",2018 1Q",2018 2Q", 2018 3Q", 2018 4Q", 2018 FY ")
$

Та же идея: (?<=[\(,])\s*(.*?)\s*(?=[,\)])

Hao Wu 23.12.2020 07:52

@JvdV .. да, это работает .. можешь добавить это как ответ

stack0114106 23.12.2020 07:56

@JvdV .. это просто пустая работа .. производительность не имеет значения ..

stack0114106 23.12.2020 08:04
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
3
124
6
Перейти к ответу Данный вопрос помечен как решенный

Ответы 6

попробуй это

(?<=\(|,)\s*(.*?)\s*(?=\)|,)

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

perl -wpe'
    s{ \(\K ([^)]+) }
     { join ", ", map { s/^\s+|\s+$//g; qq("$_") } split /,/, $1 }ex
' file

последнее значение отображается как "2018 FY " оно должно быть "2018 FY"

stack0114106 23.12.2020 08:06

@ stack0114106 Исправлено. Не вижу ничего приятнее, чем просто убрать начальные/конечные пробелы внутри map, посмотрю чуть позже...

zdim 23.12.2020 08:19

нп.. хорошего дня

stack0114106 23.12.2020 08:20

Редактировать: нужно удалить конечный пробел в map -- но тогда можно все очистить, поэтому удалили другие \s

zdim 23.12.2020 11:15
Ответ принят как подходящий

Посмотрите, работает ли для вас следующее:

[(,]\K\s*(.*?)\s*(?=[),])

Смотрите онлайн демо


  • [(,] - Сопоставьте запятую или открывающую скобку.
  • \K - Сбросить начальную точку сообщаемого матча.
  • \s* - Сопоставьте ноль или более пробелов.
  • (.*?) — 1-я группа захвата для захвата любого персонажа с ленивым квантификатором.
  • \s* - Сопоставьте ноль или более пробелов.
  • (?=[),]) - Положительный просмотр вперед для соответствия запятой или закрывающей скобке.

Согласно связанной демонстрации, замените на "\1".

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

(?:\G(?!^),|\bList\((?=[^()\r\n]*\)))\K\h*(\w+(?:\h+\w+)*)\h*

Объяснение

  • (?: Группа без захвата
    • \G(?!^), Заявите позицию в конце предыдущего матча, но не в начале (поскольку \G может совпадать в этих двух позициях)
    • | Или
    • \bList\((?=[^()\r\n]*\)) Граница слова, затем сопоставьте List( и установите закрывающий ) в той же строке
  • ) Закрыть группу без захвата
  • \K\h* Забудьте, что совпало до сих пор (чтобы не удалять совпадающие List( и запятые), и сопоставьте необязательные пробелы, которые нужно удалить.
  • ( Группа захвата 1
    • \w+(?:\h+\w+)* Совпадение 1+ словесных символов, необязательно повторяемых пробелами и словесными символами
  • )\h* Закройте группу 1 и сопоставьте необязательные конечные пробелы, которые необходимо удалить.

Демонстрация регулярных выражений

В замене используйте группу 1 между двойными кавычками "\1"

да.. работает.. но трудно понять

stack0114106 23.12.2020 13:10

у вас есть другие простые примеры для понимания \G в регулярном выражении

stack0114106 23.12.2020 13:39

@stack0114106 Вы можете увидеть, например, stackoverflow.com/questions/21971701/… или reexegg.com/regex-anchors.html#G ) или [regular-expressions.info/continue.html

The fourth bird 23.12.2020 13:46

Я пробовал в стиле \G для этого вопроса.. stackoverflow.com/questions/65435848/… можете взглянуть на это

stack0114106 24.12.2020 10:00

Еще вариант:

$ perl -pne 's/\(\s+/\(/; /([^(]+\()(.+)\)/; $_ = "$1\"".join("\",\"",split(/,\s*/,$2)).")\n"; ' file
List("UT_LVL_17_CD","UT_LVL_20_CD","2018 1Q","2018 2Q","2018 3Q","2018 4Q","2018 FY)
List("UT_LVL_17_CD","UT_LVL_20_CD","2018 1Q","2018 2Q","018     3Q","2018 4Q","2018 FY)
List("UT_LVL_17_CD","UT_LVL_20_CD","2018 1Q","2018 2Q","2018 3Q","2018 4Q","2018 FY )

Входной тестовый файл:

$ cat file
List(UT_LVL_17_CD, UT_LVL_20_CD, 2018 1Q, 2018 2Q, 2018 3Q, 2018 4Q, 2018 FY)
List(UT_LVL_17_CD,    UT_LVL_20_CD,2018 1Q,2018 2Q,018     3Q,2018 4Q,2018 FY)
List( UT_LVL_17_CD,    UT_LVL_20_CD,2018 1Q,2018 2Q, 2018 3Q, 2018 4Q, 2018 FY )

отличная..идея..расщепление /,\s*/ после первоначального очищения..

stack0114106 23.12.2020 14:41

OP упоминает, что начальные/конечные пробелы приемлемы... Я понимаю, что это также означает, что можно удалить ненужные начальные/конечные пробелы.

Пример ввода:

$ cat string.dat
List(UT_LVL_17_CD, UT_LVL_20_CD, 2018 1Q, 2018 2Q, 2018 3Q, 2018 4Q, 2018 FY)
List(UT_LVL_17_CD,UT_LVL_20_CD,2018 1Q,2018 2Q,018 3Q,2018 4Q,2018 FY)
List( UT_LVL_17_CD,    UT_LVL_20_CD,2018 1Q,2018 2Q, 2018 3Q, 2018 4Q, 2018 FY )

Одна не очень компактная awk идея:

awk -F'[()]' '                         # input field delimiters are "(" and ")"
{ printf "%s(", $1                     # print field #1 + "("
  n=split($2,a,",")                    # split field #2 by ",", save in array a[]
  pfx = ""                               # initial prefix is ""
  for (i=1 ; i<=n ; i++)               # loop through a[] elements
      { gsub(/^ *| *$/,"",a[i])        # strip leading/trailing spaces
        printf "%s\"%s\"", pfx, a[i]   # print prefix + current a[] element wrapped in double quotes
        pfx = ","                        # set prefix to "," for rest of a[] elements
      }
   printf ")\n"                        # print final ")"
}
' string.dat

Это генерирует:

List("UT_LVL_17_CD","UT_LVL_20_CD","2018 1Q","2018 2Q","2018 3Q","2018 4Q","2018 FY")
List("UT_LVL_17_CD","UT_LVL_20_CD","2018 1Q","2018 2Q","018 3Q","2018 4Q","2018 FY")
List("UT_LVL_17_CD","UT_LVL_20_CD","2018 1Q","2018 2Q","2018 3Q","2018 4Q","2018 FY")

Другие вопросы по теме