【问题标题】:Extracting line after new line在新行之后提取行
【发布时间】:2011-06-22 07:06:59
【问题描述】:

我有一个类似的文本文件

Country1
city1
city2

Country2
city3
city4

我想将国家和城市分开。有什么快速的方法吗?我正在考虑一些文件处理,然后提取到不同的文件,这是最好的方法还是可以用一些正则表达式等快速完成?

【问题讨论】:

  • 什么都行。只是想完成工作。
  • 城市是小写,国家是小写吗?
  • @k102 我在字符串上使用过它,但从未在整个文件上使用过。它也适用吗?
  • @m4rc 不,一切都是标题大小写。每个国家名称前都有一个空行。
  • @Myth emmm,对不起,我在想别的东西 =) 我发布了如何在 php 中完成此操作

标签: php python regex parsing vim


【解决方案1】:
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))

【讨论】:

    【解决方案2】:
    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']
    

    【讨论】:

      【解决方案3】:
      $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;
      }
      

      【讨论】:

        【解决方案4】:

        根据您的文件的规则程度,在 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())
        

        这对于将数据放入输出文件或将其存储在文件句柄本身之外没有任何作用,但这是一个开始。不过,您确实应该为您的问题选择一种语言。很多时候直到

        【讨论】:

          【解决方案5】:

          另一个不读取数组中整个文件的 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 数组将包含按国家/地区划分的城市列表。

          【讨论】:

            【解决方案6】:

            是否有某种模式可以区分国家和城市?还是空行后的第一行是国家,所有后续行都是城市名称,直到下一个空行?或者,您是否根据查找表(Python 中的“字典”;PHP 中的关联数组;Perl 中的哈希 --- 包括所有官方认可的国家)来查找国家/地区?

            可以假设没有名称与任何国家/地区发生冲突的城市吗?有法国爱荷华州还是日本旧美国?

            将它们分开后,您想如何处理它们?您提到“一些文件处理,然后提取到不同的文件”——您是否正在考虑每个国家/地区一个文件,其中包含其中所有城市的列表?还是每个国家一个目录,每个城市一个文件?

            显而易见的方法是逐行迭代文件并维护一个小型状态机:空(文件开头,国家之间的空白行?)在此期间您进入“国家”状态(只要您发现任何匹配任何标准的模式都意味着您遇到了一个国家/地区的名称)。找到国家/地区名称后,您就处于城市加载状态。我会创建一个字典,使用国家名称作为键和一组城市作为城市(尽管在一个国家有多个同名城市的情况下,你可能真的需要县/省、城市名称元组:波特兰、缅因州与波特兰,例如俄勒冈州)。如果您的文件内容导致某种歧义(在您确定国家之前的城市名称,连续两个国家名称,等等),您也可能会出现一些“错误”状态。

            鉴于您的规范含糊不清,很难提出一个好的代码片段。这是。

            【讨论】:

              【解决方案7】:

              不确定这是否会有所帮助,但您可以尝试使用以下代码获取字典,然后使用它(写入文件、比较等):

              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
              

              【讨论】:

                【解决方案8】:

                此正则表达式适用于您的示例:

                /(?:^|\r\r)(.+?)\r(.+?)(?=\r\r|$)/s
                

                捕获第 1 组中的国家和第 2 组中的城市。 您可能需要调整换行符,具体取决于您的系统。它们可以是\n、\r 或\r\n。编辑:添加了一个 $ 符号,所以最后不需要两个换行符。您需要 dotall 的标志才能使正则表达式按预期工作。

                【讨论】:

                  【解决方案9】:

                  使用 awk 打印字段 1 - 国家

                  awk 'BEGIN {RS="";FS="\n"} {print $1 > "countries"} {for (i=2;i<=NF;i++) print $i > "cities"}' source.txt 
                  

                  【讨论】:

                    猜你喜欢
                    • 1970-01-01
                    • 1970-01-01
                    • 2018-02-17
                    • 1970-01-01
                    • 2019-10-10
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    相关资源
                    最近更新 更多