Как найти все шаблоны между двумя символами?

Это был ноутбук Toshiba? У меня есть случайная проблема выключения из-за перегрева процессора. XFCE, вероятно, использует меньше вычислительной мощности, чем gnome, поэтому процессор не всегда работает. Я исправил его (под единицей), изменив режим процессора на «ondemand»

1
задан 12 November 2014 в 22:32

4 ответа

Ключ состоит в том, чтобы использовать кавычки в вашем выражении. Трудно сделать это с помощью одной команды grep. Вот однострочный perl:

perl -0777 -nE 'say for /"(.*?)"/sg' file

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

perl -0777 -lne 'print for /"(.*?)"/sg} BEGIN {$\="\0"' <<DATA | od -c
blah "first" blah "second
quote with newline" blah "third"
DATA
0000000   f   i   r   s   t  \0   s   e   c   o   n   d  \n   q   u   o
0000020   t   e       w   i   t   h       n   e   w   l   i   n   e  \0
0000040   t   h   i   r   d  \0
0000046
2
ответ дан 24 May 2018 в 01:56
  • 1
    Спасибо, Гленн, моя команда grep -Po ' "\K[^"]*' file работает, если у меня есть одно место перед первой левой парой " s в моем входном файле. Есть ли какое-либо заменимое regex, которое я меняю здесь здесь ... -Po '[HERE]"\K ... с этим регулярным выражением. заменяя пробел, чтобы соответствовать всем символам, например [a-zA-Z] – αғsнιη 12 November 2014 в 18:53
  • 2
    @KasiyA no. Проблема в том, что grep будет соответствовать One и распечатать его. Затем оставшийся текст ". the second is here" также совпадает. Я не думаю, что механизм PCRE от Grep имеет любой способ избежать этого. – terdon♦ 12 November 2014 в 18:57
  • 3
    поэтому я написал, что выражение должно потреблять конечную цитату. – glenn jackman 12 November 2014 в 20:41
  • 4
    @glennjackman точно. Вы знаете, возможно ли это в grep? – terdon♦ 12 November 2014 в 20:43

Это может быть возможно с нижним слоем grep one liner, и я предположил, что у вас есть сбалансированные кавычки.

grep -oP '"\s*\K[^"]+?(?=\s*"(?:[^"]*"[^"]*")*[^"]*$)' file

Пример:

$ cat file
first matched is "One". the second is here"Two "
and here are in second line" Three ""Four".
$ grep -oP '"\s*\K[^"]+?(?=\s*"(?:[^"]*"[^"]*")*[^"]*$)' file
One
Two
Three
Four

Другое решение для вытягивания волос через Глагол PCRE (*SKIP)(*F),

$ grep -oP '[^"]+(?=(?:"[^"]*"[^"]*)*[^"]*$)(*SKIP)(*F)|\s*\K[^"]+(?=\b\s*)' file
One
Two
Three
Four
1
ответ дан 24 May 2018 в 01:56
  • 1
    да, я сделаю это. Это решение для этого вопроса также :-) – Avinash Raj 17 November 2014 в 10:27

Использование sed:

sed 's/[^"]*"\([^"]\+\)"[^"]*/\1\n/g' file
[^"]*

^ в начале [^"]* ... означает, что символы, перечисленные в классе символов, не должны матч (только совпадение с одним "). [F8] означает " может происходить ноль или более раз.

"\([^"]\+\)"

Все внутри \(...\) является подходящей группой. Первый символ за пределами сопоставимой группы - это совпадение начала. Класс символов [^"] следующий (он соответствует каждому символу, кроме "). Квантификатор \+ означает, что в кавычках ("...") в вашем входном файле должен быть по крайней мере один символ. Затем \), конец соответствующей группы. Эта сопоставляющая группа может получить доступ по индексу через \1.

Последняя часть [^"]* совпадает с первой частью, которая соответствует всем, до следующего ".

1
ответ дан 24 May 2018 в 01:56

Альтернативный подход с Python, который не требует регулярных выражений (хотя и не совсем надежных), заключается в обработке каждой строки в символе текстового файла по символу.

Основная идея того, как это работает: если мы видим двойную кавычку и флаг не поднят - поднимите флаг, и если мы увидим его снова, а флаг будет поднят - опустите флаг. Когда флаг поднят - так мы знаем, что мы находимся в двойных кавычках, поэтому мы можем хранить последующие символы. Как только флаг будет опущен, распечатайте то, что мы прочитали.

#!/usr/bin/env python
from __future__ import print_function
import sys

flag=False
quoted_string=[]
for line in sys.stdin:
    for char in line.strip():
        if char == '"':
           if flag:
               flag=False
               if quoted_string:
                  print("".join(quoted_string))
                  quoted_string=[]
           else:
               flag=True
               continue 
        if flag:
           quoted_string.append(char)

И тестовый прогон:

$ cat input.txt
first matched is "One". the second is here"Two "
and here are in second line" Three ""Four".

$ ./get_quoted_words.py < input.txt                                                                                      
One
Two 
 Three 
Four
0
ответ дан 24 May 2018 в 01:56

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

Похожие вопросы: