如何提取括号内包含特定单词的文本?

如何提取括号内包含特定单词的文本?

我怎样才能转换这个:

foo (blah) (bar 80)
foo (cats) (blat 92)

对此:

foo bar 80
foo blat 92

我想保留所有不在括号中的文本。

我只想提取括号内包含字符串“bar”或“blat”的文本。

不包含“blat”或“bar”的括号对应该被忽略。

最好使用 Sed 或 awk

答案1

使用sed

< inputfile sed 's/(\([^\)]*\(bar\|blat\)[^\)]*\))/\1/g; s/(.*) //g'

输入文件:

test (bar) (blat)
bar (testblat) (bartest)
blat (testbar) (barblat) (no) (blatanother)

输出文件:

test bar blat
bar testblat bartest
blat testbar barblat blatanother

分解

#1:

  • (: 匹配一个(字符
  • \(:开始对捕获组进行分组
  • [^\)]*: 匹配 0 个或多个字符,不)
  • \(:开始对允许的字符串进行分组
  • bar:匹配第一个允许的字符串
  • \|: 分隔第二个允许的字符串
  • blat:匹配第二个允许的字符串
  • \):停止对允许的字符串进行分组
  • [^\)]*: 匹配 0 个或多个字符,不)
  • \):停止对捕获组进行分组
  • ): 匹配一个)字符

#2:

  • (: 匹配一个(字符
  • .*: 匹配 0 个或多个字符
  • ): 匹配一个)字符
  • : 匹配一个字符

答案2

虽然这在sed或中确实是可能的awk,但使用 Perl 要容易得多(至少对我来说):

$ perl -ple '@pars=( /(\(.+?\))/g ); 
              for $par (@pars){
                s/\s*.$par.// unless $par=~/blat|bar/
              } s/[()]//g;' file
foo bar 80
foo blat 92

解释

  • -ple:在输入文件上执行脚本p后,打印输入文件的每一行。删除尾随换行符,并在每次调用时添加换行符。e-lprint
  • @pars=( /(\(.+?\))/g );@pars数组现在包含括号内的所有字符串。
  • for $par (@pars){ ... }:针对上面找到的每个字符串。
  • s/\s*.$par.// unless $par=~/blat|bar/:如果这组括号不包含blat或,则删除它们bar
  • s/[()]//g;:删除所有括号(而不是括号内的文本)。

您还可以高尔夫球将以上内容浓缩为

perl -ple 'for$par((/(\(.+?\))/g)){$par=~/blat|bar/||s/\s*.$par.//};s/[()]//g;' file

答案3

使用python

#!/usr/bin/env python2
import re
with open('/path/to/file.txt') as f:
    for line in f:
        pat_list = re.findall(r'\(([^)]*?)\)', line.rstrip())
        for pat in pat_list:
            if not re.search(r'(?:blat|bar)', pat):
                print re.sub(r'\(|\)', '', line.replace(' ({0})'.format(pat), '').rstrip())

输出:

foo bar 80
foo blat 92
  • 这里我们使用了的re(正则表达式)模块python
  • pat_list将包含括号内的字符串列表
  • pat_list然后我们在成员中搜索“blat”或“bar”的存在
  • 如果没有找到,我们将打印该行并删除不必要的部分,包括括号。

答案4

有点晚了,但是,单线简单的力量怎么样:

> cat test.py
from string import replace

stuff = '''
foo (blah) (bar 80)
foo (cats) (blat 92)
'''

for i in stuff.split('\n'):  # split by \n
  if i != str():  # not empty string
    print ''.join(i.split()[0]+' '+i.split()[2]+' '+i.split()[3]).replace('(','').replace(')','')

>>> python test.py 
foo bar 80
foo blat 92

相关内容