匹配'。'的每次出现。除了最后

时间:2016-11-07 19:14:10

标签: regex sed

输入数据(文件名):

Word1.Word2 Word3.ext
Word1.Word2 Word3.Word4.ext
Word1 Word2.Word2.ext
Word1 Word2.Word3 Word4.ext

其中.ext根据文件类型而有所不同,而单词则以空格或'分隔。'

期望的输出:

Word1 Word2 Word3.ext
Word1 Word2 Word3 Word4.ext
Word1 Word2 Word3.ext
Word1 Word2 Word3 Word4.ext

我知道我可以替换每一次'。':

s/\\./ /

我知道我可以拿到最后一个。扩展名为:

(.[^\\.]*)$

但我无法弄清楚如何将它们加在一起。

3 个答案:

答案 0 :(得分:0)

使用perl lookahead regex:

更容易实现
perl -pe 's/\.(?=.*\.[^.]*$)/ $1/g' file

Word1 Word2 Word3.ext
Word1 Word2 Word3.Word4.ext
Word1 Word2 Word2.ext
Word1 Word2 Word3 Word4.ext

或者使用此awk命令:

awk -F '.' '{$(NF-1) = $(NF-1) "." $NF; NF--} 1' file

Word1 Word2 Word3.ext
Word1 Word2 Word3 Word4.ext
Word1 Word2 Word2.ext
Word1 Word2 Word3 Word4.ext

如果必须使用sed,请使用:

sed ':a
s/\.\([^.]*\.\)/ \1/g
ta' file

Word1 Word2 Word3.ext
Word1 Word2 Word3 Word4.ext
Word1 Word2 Word2.ext
Word1 Word2 Word3 Word4.ext

答案 1 :(得分:0)

这是一种不依赖于扩展正则表达式的方法,只需库存sed

sed 'h;s/.*\(\.[^.]*\)/\1/;x;s/\.[^.]*$//;s/\./ /g;G;s/\n//'

命令由分号分隔并执行以下操作:

  • h将该行复制到保留空间,在我们工作时保留原始文本
  • s删除除最后一个点和扩展名之外的所有内容,并且正则表达式中不需要美元符号,因为.*足够贪婪,可以尽可能多地占用该行,< / LI>
  • x将此点和扩展名与我们在保留空间中保存的原始行进行交换,
  • s删除原始行的最后一个点和扩展名
  • s用空格替换每个剩余的点(g修饰符意味着替换所有这些点,而不仅仅是第一个),
  • G将我们保存在保留空间中的点和扩展名附加到无点线上(但用换行符分隔它们),
  • s删除了令人讨厌的换行符。

关于您原始帖子的一个注释:您的期间和分机的正则表达式,您显示为

(.[^\\.]*)$

应该是

\.[^.]*$

在方括号之外,句点与任何字符匹配,因此如果要匹配句点,则需要使用反斜杠对其进行转义。但在方括号内,它只匹配一个句号。除非你试图捕获匹配的字符串,否则你可以删除它们。

答案 2 :(得分:0)

以下RE发现:

  • 查找。
  • 除了点之外的任何东西。
  • 找到。再次
  • 除了点之外的任何东西。
  • EOL
import win32com.client

connection = win32com.client.Dispatch(r'ADODB.Connection')
DSN = 'PROVIDER=Microsoft.Jet.OLEDB.4.0;DATA SOURCE=c:\\testdb.mdb;'
connection.Open(DSN)
recordset = win32com.client.Dispatch(r'ADODB.Recordset')
recordset.Open('SELECT * FROM Table1', connection, 1, 3)
fields_dict = {}
for x in range(recordset.Fields.Count):
    fields_dict[x] = recordset.Fields.Item(x).Name
    print fields_dict[x], recordset.Fields.Item(x).Value
除了领先的&#34;。&#34; 然后用&#34;替换$ 1和#34;