我有一个类似的文本文件
Country1
city1
city2
Country2
city3
city4
我想把乡村和城市分开。有什么快速的方法吗?我正在考虑一些文件处理,然后提取到不同的文件,这是最好的方法还是可以用一些正则表达式等快速完成?
countries=[]
cities=[]
with open("countries.txt") as f:
gap=True
for line in f:
line=line.strip()
if gap:
countries.append(line)
gap=False
elif line=="":
gap=True
else:
cities.append(line)
print countries
print cities
输出:
['Country1', 'Country2']
['city1', 'city2', 'city3', 'city4']
如果您想将这些写入文件:
with open("countries.txt","w") as country_file, open("cities.txt","w") as city_file:
country_file.write("'n".join(countries))
city_file.write("'n".join(cities))
f = open('b.txt', 'r')
status = True
country = []
city = []
for line in f:
line = line.strip(''n').strip()
if line:
if status:
country.append(line)
status = False
else:
city.append(line)
else:
status = True
print country
print city
output :
>>['city1', 'city2', 'city3', 'city4']
>>['Country1', 'Country2']
$countries = array();
$cities = array();
$gap = false;
$file = file('path/to/file');
foreach($file as $line)
{
if($line == '') $gap = true;
elseif ($line != '' and $gap)
{
$countries[] = $line;
$gap = false;
}
elseif ($line != '' and !$gap) $cities[] = $line;
}
根据您的文件的规则性,它在python中可能很简单:
with open('inputfile.txt') as fh:
# To iterate over the entire file.
for country in fh:
cityLines = [next(fh) for _i in range(2)]
# read a blank line to advance countries.
next(fh)
这不太可能完全正确,因为我认为许多国家的城市数量各不相同。你可以这样修改它来解决这个问题:
with open('inputfile.txt') as fh:
# To iterate over the entire file.
for country in fh:
# we assume here that each country has at least 1 city.
cities = [next(fh).strip()]
while cities[-1]: # will continue until we encounter a blank line.
cities.append(next(fh).strip())
这对将数据放入输出文件或将其存储在文件句柄本身之外没有任何作用,但这只是一个开始。不过,你真的应该为你的问题选择一种语言。很多时间直到
另一个不读取数组中整个文件的PHP示例。
<?php
$fh = fopen('countries.txt', 'r');
$countries = array();
$cities = array();
while ( $data = fgets($fh) )
{
// If $country is empty (or not defined), the this line is a country.
if ( ! isset($country) )
{
$country = trim($data);
$countries[] = $country;
}
// If an empty line is found, unset $country.
elseif ( ! trim($data) )
unset($country);
// City
else
$cities[$country][] = trim($data);
}
fclose($fh);
$countries
数组将包含国家列表,而$cities
数组将包含按国家列出的城市列表。
是否存在区分国家和城市的模式?还是空白行后的第一行是一个国家,所有后续行都是城市名称,直到下一个空白行?或者,你是根据查找表(Python中的"字典";PHP中的关联数组;Perl中的哈希——包括所有官方认可的国家)来查找国家吗?
假设没有城市的名字与任何国家相冲突,这安全吗?有法国,爱荷华州,美国,还是旧的美国,日本?
在将它们分离后,你想对它们做什么?你提到"一些文件处理,然后提取到不同的文件"——你是否想过每个国家一个文件,其中包含所有城市的列表?还是每个国家一个目录,每个城市一个文件?
显而易见的方法是逐行迭代文件,并维护一个小的状态机:空(文件的开头,国家之间的空行?),在此期间,您将进入"国家"状态(无论何时,只要您发现任何符合任何标准的模式,都意味着您遇到了国家的名称)。一旦你找到了一个国家名称,那么你就进入了城市加载状态。我会创建一个字典,使用国家名称作为关键字,使用一组城市作为城市(尽管在一个国家有多个同名城市的情况下,你可能真的需要县/省、城市名称元组:例如,缅因州波特兰与俄勒冈州波特兰)。如果文件的内容导致某种歧义(在确定一个国家之前的城市名称,连续两个国家名称,等等),你也可能会有一些"错误"状态。
考虑到这里的规范有多模糊,很难提出一个好的代码片段。
不确定这是否有帮助,但您可以尝试使用以下代码来获取字典,然后使用它(写入文件、比较等):
res = {}
with open('c:''tst.txt') as f:
lines = f.readlines()
for i,line in enumerate(lines):
line = line.strip()
if (i == 0 and line):
key = line
res[key] = []
elif not line and i+1 < len(lines):
key = lines[i+1].strip()
res[key] = []
elif line and line != key:
res[key].append(line)
print res
此正则表达式适用于您的示例:
/(?:^|'r'r)(.+?)'r(.+?)(?='r'r|$)/s
捕获第1组中的国家和第2组中的城市。根据您的系统,您可能需要调整换行符。它们可以是''n、''r''n或''r''n。edit:添加了一个$符号,所以你不需要在末尾有两个换行符。您需要dotall的标志,regex才能按预期工作。
使用awk-countries 打印过滤1
awk 'BEGIN {RS="";FS="'n"} {print $1 > "countries"} {for (i=2;i<=NF;i++) print $i > "cities"}' source.txt