如何根据缩进解析块

时间:2013-03-02 16:14:25

标签: python algorithm parsing indentation

我正在编写一个从类似Markdown的标记到HTML的翻译器。我已经完成了脚本,除了有序/无序列表转换。我想基于重要的空白(也称为偏离规则)来格式化列表。示例有效输入如下:

:: List item 
   top level
 :: List item level 2
 :: List item level 2
    :: List item level 3
      :: List item level 4
 :: List item level 2

:: List item top level

::表示列表项。缩进级别可能是任意的。标签不重要。我一直致力于纸上解决方案,但我无法找到实施的方法。我应该怎么做呢?

P.S:只要它不止一个,任何空格的任何仲裁表示一个新的级别,就像在python中一样。

我正在使用python实现这一点,但我不是在寻找代码。我想要解释如何做。最好我想自己实现完整的东西,没有任何库。我将把这个标记用于我的jekyll博客,但这对我来说不仅仅是一个小工具,我想尽可能多地学习正则表达式和从这个项目解析。提前谢谢。

2 个答案:

答案 0 :(得分:2)

@ delnan与Python reference的链接提供了一个很好的方法,但是(正如参考文献所暗示的那样)Python允许正确的缩进,这也是令人困惑的阅读和(如果你试图充分利用它的完全自由)潜在的棘手的调试。

对于您的应用程序,如果您需要每个唯一数量的缩进空格来指示不同的列表级别,则可能不会让用户感到困惑。对于那些语义,您可以在不超过四行的Python 3中找到列表的级别。您不希望在代码中看到解决方案(尽管我很乐意发布它,如果您愿意)所以我的方法大致如下:

  1. 计算列表每行开头的空格数(不需要正则表达式)。
  2. 创建一个集合并对其进行排序,以提供用于此列表的每个级别的缩进空间数量列表,从最少到最多排序。
  3. 创建一个字典,将每种情况下使用的缩进空格数与列表级别相关联。
  4. 使用列表每行开头的空格数来表示该字典,它给出了每行的列表级别。
  5. (已编辑以包含代码并处理多行列表项)

    假设:

    :: List item
       (this is the second line of the first list item)
     :: List item level 2
     :: List item level 2
        :: List item level 3
          :: List item level 4
     :: List item level 2
    :: List item top leve
    

    ...下面的函数产生列表:

    :: List item (this is the second line of the first list item)
     :: List item level 2
     :: List item level 2
      :: List item level 3
       :: List item level 4
     :: List item level 2
    :: List item top level
    

    ...我认为这是此测试案例的预期结果。

    这是为了接受标准输入列表而编写的代码:

    import sys
    
    def findIndent (lst):
        # given a list of text strings, returns a list containing the
        # indentation levels for each string
        spcCount = [len(s)-len(s.lstrip(' ')) for s in lst]
        indent = sorted(set(spcCount))
        levelRef = {indent[i]:i for i in range(len(indent))}
        return [levelRef[i]+1 for i in spcCount]
    
    lst = []
    for li in sys.stdin:
        if li.lstrip(' ').find('::') == 0:
            lst.append(li.rstrip())
        else:
            lst[-1] = lst[-1].rstrip() + ' ' + li.lstrip(' ').rstrip()
    
    for i,li in zip(findIndent(lst),lst):
        print (' '*i + li.lstrip())
    

答案 1 :(得分:0)

不是答案,但我需要格式化。

这应解析哪些级别的列表?

:: List item level 
  :: List item level ?
 :: List item level ?
    :: List item level ?
 :: List item level ?
   :: List item level ?

我认为你正在努力应对列表中没有任何意义的极端情况,而实际上你应该告诉用户写一些更有效的东西。