【问题标题】:Remove trailing and leading char using csv.reader使用 csv.reader 删除尾随和前导字符
【发布时间】:2018-11-15 07:34:59
【问题描述】:

如果我在 csv 的第二列中的值以“(”或以“)”开头,我如何删除某个字符,我对 python 很陌生,请帮我解决这个问题

示例:

0023632fa4a860be8bc85ddf39fc19c3c4c2e6fe,(Java Archive (JAR) 4049-0),Not Supported,
005c41fc0f8580f51644493fcbaa0d2d468312c3,(WIN32 EXE 7-2),Ransom.Win32.TRX.XXPE50FFF027,

0023632fa4a860be8bc85ddf39fc19c3c4c2e6fe,Java Archive (JAR) 4049-0,Not Supported,
005c41fc0f8580f51644493fcbaa0d2d468312c3,WIN32 EXE 7-2,Ransom.Win32.TRX.XXPE50FFF027,

我有这段代码使用 DATA INFILE

TRIM(TRAILING ')' FROM TRIM(LEADING '('

如何在我的代码中应用它:

with open(fullPath, 'rb') as file:
     csv_data = csv.reader(file)
     next(csv_data)

【问题讨论】:

  • 给出一个应该如何转换该行的示例。
  • 更新了我的问题
  • 为什么(JAR) 还存在呢?
  • 因为我只需要删除字符串开头和结尾的()

标签: python csv


【解决方案1】:

使用lstrip()rstrip() 的解决方案

import csv

new_rows = []
with open('test.csv', 'rt') as file:
    csv_data = csv.reader(file, delimiter=',')
    for row in csv_data:
        new_rows.append([row[0],row[1].lstrip('(').rstrip(')'),row[2]])

print(new_rows) # Outputs ['0023632fa4a860be8bc85ddf39fc19c3c4c2e6fe,Java Archive (JAR) 4049-0Not Supported', '005c41fc0f8580f51644493fcbaa0d2d468312c3,WIN32 EXE 7-2ansom.Win32.TRX.XXPE50FFF027']

编辑

要将编辑保存在新的 .csv 文件中,只需添加:

with open('test2.csv', 'wt') as file:
    writer = csv.writer(file)
    for row in new_rows:
        writer.writerow(row)

【讨论】:

  • 我该如何换行? itried new_rows.append(row[0]+','+row[1].lstrip('(').rstrip(')')+','+row[2] + "\n") 所以数组会像 csv 但它不起作用
  • 我需要使用 "\n" 打破它,所以打印时它会按行显示
  • 获取每行的行只需使用:for line in new_rows: print(line)
  • 是否可以将其保存到更新的 csv 中?因为我试图将我的 csv 导入数据库
  • 我已经包含了将new_rows写入test2.csv文件的代码。如果这对您有所帮助,请考虑投票并接受答案。谢谢。
【解决方案2】:

这是一种方法,我已经从字符串中替换了第一次出现和最后一次出现的 '(' 和 ')'。希望对您有所帮助。

s = '''0023632fa4a860be8bc85ddf39fc19c3c4c2e6fe,(Java Archive (JAR) 4049-0),Not Supported,
005c41fc0f8580f51644493fcbaa0d2d468312c3,(WIN32 EXE 7-2),Ransom.Win32.TRX.XXPE50FFF027,'''

def last_replace(s, old, new, occurrence):
    '''Replaces the last occurence of the character'''
    li = s.rsplit(old, occurrence)
    return new.join(li)

new_string = [last_replace(line, ')', '', 1).replace('(', '', 1) for line in s.split('\n')]
print(new_string)

输出:

['0023632fa4a860be8bc85ddf39fc19c3c4c2e6fe,Java Archive (JAR) 4049-0,Not Supported,',
'005c41fc0f8580f51644493fcbaa0d2d468312c3,WIN32 EXE 7-2,Ransom.Win32.TRX.XXPE50FFF027,']

PS : 我从here 窃取了last_replace 函数

【讨论】:

  • line.lstrip('(').rstrip(')') 怎么样?
  • 是的,这也可以,采用这种方法,因此以后可以轻松替换多个()
【解决方案3】:

这是了解regular expressions 的绝佳机会!正则表达式是一种识别和处理文本模式的方法。 Python 有一个正则表达式包作为其标准库的一部分。我将假设您在此答案的其余部分使用 Python 3,其中包名为 re

TLDR 对您的问题的回答是:

import re

string_without_parens = re.sub(r'(^\()|(\)$)', '', string_maybe_has_parens)

但是,这里发生了什么? re.sub() 函数接受三个参数,一个正则表达式字符串(由前导 r 表示)、一个要替换每个匹配项的字符串以及要替换的字符串。这里的正则表达式是 @987654328 @。那么这是什么意思呢?让我们一步一步来:

  • 一组括号() 代表一个捕获组,这些可用于获取匹配项,但我已将它们用作将我们正在寻找的字符组合在一起的一种方式。此正则表达式中有两个捕获组:(^\()(\)$)
  • 在它们之间是一个| 字符,这表示正则表达式语言中的OR,所以它正在寻找匹配(^\() (\)$) 的东西。
  • 第一个捕获组(^\():里面有两个东西(嗯,真的三个,但我们会谈到那个)。第一个是^,这就是所谓的anchor,这个特别说,“只看字符串的开头”。第二个(和第三个)字符是\(,上面写着“我想寻找一个左括号”。因为括号在正则表达式中使用,我们必须使用反斜杠字符来“转义”它。
  • 第二个捕获组(\)$):包含一个转义的右括号\) 和其他锚。这个锚点代表字符串的结尾,就像^ 代表开始一样。
  • 总而言之:“匹配开头的左括号或结尾的右括号”,re.sub() 函数说用 '' 替换任何与此模式匹配的内容(即什么都没有)。

希望对您有所帮助!如果你想更多地使用正则表达式,你可以试试regexr,它帮助我理解了它们。

【讨论】:

  • 如果你只想替换()这样效率会很低
  • "有些人在遇到问题时会想'我知道,我会使用正则表达式'。现在他们有两个问题。” - 杰米扎温斯基
  • @VineethSai 正则表达式可以编译为在 O(n) 中运行的 DFA,我怀疑使用锚点会将其优化为 O(1)。您对replace 方法的使用使您的解决方案为 O(n)。 “正则表达式很慢”的一揽子声明并没有真正帮助任何人。如果您想了解有关正则表达式速度的更多信息,我建议您阅读一下:swtch.com/~rsc/regexp/regexp1.html。正则表达式还提供紧凑、易于理解的语法(在本例中为单行)。
猜你喜欢
  • 2020-11-24
  • 2013-02-10
  • 2017-08-03
  • 1970-01-01
  • 2021-12-29
  • 2014-08-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多