У меня есть список строк, который выводится на консоль. Мне нужно преобразовать его обратно в строку в кавычках.
Предположим, что файл примера выглядит следующим образом:
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 ")
$
@JvdV .. да, это работает .. можешь добавить это как ответ
@JvdV .. это просто пустая работа .. производительность не имеет значения ..
попробуй это
(?<=\(|,)\s*(.*?)\s*(?=\)|,)
с помощью этого регулярного выражения вы можете сопоставить каждый текст с группой, которая не содержит пробела в начале и в конце, а затем добавить к нему ""
посмотри демо
perl -wpe'
s{ \(\K ([^)]+) }
{ join ", ", map { s/^\s+|\s+$//g; qq("$_") } split /,/, $1 }ex
' file
последнее значение отображается как "2018 FY "
оно должно быть "2018 FY"
@ stack0114106 Исправлено. Не вижу ничего приятнее, чем просто убрать начальные/конечные пробелы внутри map
, посмотрю чуть позже...
нп.. хорошего дня
Редактировать: нужно удалить конечный пробел в map
-- но тогда можно все очистить, поэтому удалили другие \s
Посмотрите, работает ли для вас следующее:
[(,]\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"
да.. работает.. но трудно понять
у вас есть другие простые примеры для понимания \G в регулярном выражении
@stack0114106 Вы можете увидеть, например, stackoverflow.com/questions/21971701/… или reexegg.com/regex-anchors.html#G ) или [regular-expressions.info/continue.html
Я пробовал в стиле \G для этого вопроса.. stackoverflow.com/questions/65435848/… можете взглянуть на это
Еще вариант:
$ 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*/
после первоначального очищения..
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")
Та же идея: (?<=[\(,])\s*(.*?)\s*(?=[,\)])