Неудар в лунку:
19. "foo foo" (bar bar) (19) raboof
"foo foo" raboof
Expected output:
"foo foo" (bar bar) (19)
"foo foo"
Эксперт you хан see, I would like to keep the double quotes and parentheses.
Everything that is not between double quotes or parentheses should be переместите.
Используя python
:
#!/usr/bin/env python2
import re, sys
with open(sys.argv[1]) as f:
for line in f:
parts = line.split()
for i in parts:
if re.search(r'^[("].*[)"]$', i):
print i,
print '\n'.lstrip()
Вывод:
"foo" (bar) (19)
"foo"
Каждая строка читается, и части, разделенные пробелами, сохраняются в названный список parts
Затем при помощи re
модуль search
функционируйте мы нашли части, которые начинаются также "
или (
и конец с также "
или )
.
Как работать:
Сохраните сценарий как, например. script.py
. Теперь можно выполнить его двумя способами:
Сделайте это исполняемым файлом chmod u+x /path/to/script.py
и выполненный это как /path/to/script.py /path/to/file.txt
т.е. вход файл file.txt
как первый аргумент. Если и сценарий и файл находятся в том же каталоге, то из того каталога ./script.py file.txt
Можно выполнить его, не делая его исполняемым файлом, выполнить его как python2 script.py file.txt
.
Ответьте на отредактированный вопрос:
#!/usr/bin/env python2
import re, sys
with open(sys.argv[1]) as f:
for line in f:
print ''.join(re.findall(r'(?:(?<=\s)["(].*[")](?=\s|$)|(?<=^)["(].*[")](?=\s|$))', line))
Вывод:
"foo foo" (bar bar) (19)
"foo foo"
Если Вы (или кто-то еще с подобной проблемой, кто читает это) не должны сохранять новые строки, следующее работало бы:
grep -Eo '"[^"]*"|\([^)]*\)'
Для входа
19. "foo foo" (bar bar) (19) raboof
"foo foo" raboof
это приводит к выводу
"foo foo"
(bar bar)
(19)
"foo foo"
при необходимости в новых строках можно использовать некоторые приемы, например, это:
sed 's/$/\$/' \
| grep -Eo '"[^"]*"|\([^)]*\)|\$' \
| tr '\n первое sed
добавляет $
до конца каждой строки. (Вы могли использовать любой символ для этого.) Второе является почти тем же grep
как выше, но теперь также соответствует $
в конце строки, таким образом, она соответствует каждому концу строки. Эти tr
превращает новые строки в пробелы и доллары в новые строки. Но так как вывод перед тем tr
имел $
сопровождаемый новой строкой, вывод после того, как будут следовать за новой строкой пространством. Финал sed
избавляется от тех пробелов.
' \n' \
| sed 's/^ //'
первое sed
добавляет $
до конца каждой строки. (Вы могли использовать любой символ для этого.) Второе является почти тем же grep
как выше, но теперь также соответствует $
в конце строки, таким образом, она соответствует каждому концу строки. Эти tr
превращает новые строки в пробелы и доллары в новые строки. Но так как вывод перед тем tr
имел $
сопровождаемый новой строкой, вывод после того, как будут следовать за новой строкой пространством. Финал sed
избавляется от тех пробелов.
Как perl
сценарий:
$filename=$ARGV[0];
if (open(my $fh, '<:encoding(UTF-8)', $filename)) {
while (my $match = <$fh>) {
while ($match =~ /((\(.*?[^)]\))|(".*?"))/g) {
print "$1 ";
}
print "\n"
}
}
Или как perl
острота:
perl -ne 'while (/((\(.*?[^)]\))|(".*?"))/g) {print "$1 ";} print "\n"' file
Вывод
"foo foo" (bar bar) (19)
"foo foo"
<час> <час> , Который был исходная задача :
Вход:
- "нечто" (панель) (19)
raboof "нечто" raboof
Ожидаемый вывод:
"нечто" (панель) (19)
"нечто"
Используя perl
:
perl -pe '@elements=( split (/\s/) );
for $element (@elements) {
if ($element!~/^"|\(/ and $element!~/"|\($/) {
s/$element//
}
s/^\s+//;
s/\s+$/\n/
};' file
или как острота:
perl -pe '@elements=( split (/\s/) ); for $element (@elements) { if ($element!~/^"|\(/ and $element!~/"|\($/) { s/$element// } s/^\s+//; s/\s+$/\n/ };' file
Вывод:
"foo" (bar) (19)
"foo"
Ниже простого Python код сделает это задание.
import re
with open('file') as f:
reg = re.compile(r'"[^"]*"|\([^)]*\)')
for line in f:
print(' '.join(reg.findall(line)))
И другой через Perl, который использует только regex,
$ perl -pe 's/(?:"[^"]*"|\([^)]*\))(*SKIP)(*F)|\S//g;s/^\h+|\h+$|(\h)+/\1/g' file
"foo foo" (bar bar) (19)
"foo foo"
PHP был бы:
if (preg_match_all('/"(?:[^"\\\\]+|\\\\.)+"|\\([^)]+\\)/', $input, $matches)) {
echo implode(' ', $matches[0]);
}
Это также правильно обрабатывает оставленные символы в заключенных в кавычки строках (например, "Test \"string\""
рассматривается как одну строку.
Новая версия (пробелы, позволенные между ()
или ""
):
Попробуйте ниже perl
команда (кредиты: @steeldriver)
perl -ne 'printf "%s\n", join(" " , $_ =~ /["(].*?[)"]/g)'
Начальная версия (никакие пробелы между ()
или ""
)
Можно попробовать следующее perl
острота:
$ perl -ne '@a=split(/\s+/, $_); for (@a) {print "$_ " if /[("].*?[)"]/ };print"\n"' file
Другая опция Python:
#!/usr/bin/env python3
import sys
match = lambda ch1, ch2, w: all([w.startswith(ch1), w.endswith(ch2)])
for l in open(sys.argv[1]).read().splitlines():
matches = [w for w in l.split() if any([match("(", ")", w), match('"', '"', w)])]
print((" ").join(matches))
Скопируйте сценарий в пустой файл, сохраните сценарий как filter.py
Выполните его с командой:
python3 /path/to/filter.py <file>
Если мы предполагаем, что на каждом вводном символе существует заключительный символ: '('
и '"'
(мы должны предположить, что, с тех пор иначе или файл был бы неправильным или вопрос, должен будет упомянуть более сложный подшипник в случае "вложенных" круглых скобок или кавычек), код ниже должен сделать задание также:
#!/usr/bin/env python3
import sys
chunks = lambda l: [l[i:i + 2] for i in range(0, len(l), 2)]
for l in open(sys.argv[1]).read().splitlines():
words = chunks([i for i in range(len(l)) if l[i] in ['(', ')', '"']])
print((" ").join([l[w[0]:w[1]+1] for w in words]))
Это перечисляет символы в списке: ['(', ')', '"']
, делает блоки два из найденных соответствий и печати, что находится в диапазоне каждой пары:
19. "foo" (bar bar) (blub blub blub blub) (19) raboof
"foo" raboof
затем произведет:
"foo" (bar bar) (blub blub blub blub) (19)
"foo"
Использование точно похоже на первый сценарий.
Больше или другие "триггеры" могут быть легко добавлены путем добавления обеих сторон (запустите - и конечный символ строки или раздела для "сохранения") в списке:
['(', ')', '"']
в строке:
words = chunks([i for i in range(len(l)) if l[i] in ['(', ')', '"']])
Другой perl
:
$ perl -nle 'print join " ", $_ =~ /".*?"|\(.*?\)/g' file
"foo foo" (bar bar) (19)
"foo foo"