我有一组带有;
分隔符的.csv文件。我需要用空格替换数据中的某些垃圾值。示例问题行是:
103273;CAN D MAT;B.C.;B.C.;B.C.;03-Apr-2006
查找和替换后的所需行是:
103273;CAN D MAT;;;;03-Apr-2006
在上面的示例中,我将;B.C.;
替换为;;
我不能只替换B.C.
,因为我需要匹配此特定错误情况的整个单元格值。我正在使用的代码是:
import os, fnmatch
def findReplace(directory, filePattern):
for path, dirs, files in os.walk(os.path.abspath(directory)):
for filename in fnmatch.filter(files, filePattern):
filepath = os.path.join(path, filename)
with open(filepath) as f:
s = f.read()
for [find, replace] in zip([';#DIV/0!;',';B.C.;'],[';;',';;']
s = s.replace(find, replace)
with open(filepath, "w") as f:
f.write(s)
findReplace(*Path*, "*.csv")
我得到的输出是:
103273;CAN D MAT;;B.C.;;03-Apr-2006
有人可以帮忙解决这个问题吗?
提前致谢!
答案 0 :(得分:2)
[find, replacement]
对不适合您的目的。
用;
替换;
+值+ ;;
实际上只是一种复杂的方式,表示您要删除value
列。
所以不要使用[find, replacement]
对,
将;
上的行拆分为字段会更自然,更直接,
用空字符串替换被认为是垃圾的值,
然后再次加入值:
JUNK = frozenset(['#DIV/0!', 'B.C.'])
def clean(s):
return ';'.join(map(lambda x: '' if x in JUNK else x, s.split(';')))
您可以在实现中使用此功能(或将其内联复制):
def findReplace(directory, filePattern):
for path, dirs, files in os.walk(os.path.abspath(directory)):
for filename in fnmatch.filter(files, filePattern):
filepath = os.path.join(path, filename)
cleaned_lines = []
with open(filepath) as f:
for line in f.read():
cleaned_lines.append(clean(line))
with open(filepath, "w") as f:
f.write('\n'.join(cleaned_lines))
答案 1 :(得分:1)
str.replace
,一旦进行了一次替换,就会在替换后的最后一个字符后继续扫描下一个字符。因此,当两个;B.C.;
重叠时,它不会替换两者。
只有当B.C.
出现在两个;
之间时,您可以使用the re
module替换>>> import re
>>> s = "103273;CAN D MAT;B.C.;B.C.;B.C.;03-Apr-2006"
>>> re.sub(r'(?<=;)B[.]C[.](?=;)', "", s)
'103273;CAN D MAT;;;;03-Apr-2006'
,使用前瞻和后瞻断言:
;
...但在这种情况下,最好将行拆分为>>> fields = s.split(';')
>>> for i, f in enumerate(fields):
... if f in ('B.C.', '#DIV/0!'):
... fields[i] = ''
...
>>> ';'.join(fields)
'103273;CAN D MAT;;;;03-Apr-2006'
上的字段,替换与要删除的字符串匹配的字段,然后再将字符串连接在一起。
;
这有两个主要优点:您不必为每个替换的字符串编写相当复杂的正则表达式;如果其中一个字段位于该行的开头或结尾,它仍然有效。
对于任何比此更复杂的CSV解析(例如,如果任何字段可以包含引用的$this->db->set('status','og');
$this->db->where('my_date_time < NOW()',false);
$this->db->update('mytable');
个字符,或者如果文件具有应跳过的标题),请查看csv
module。