用指定的替换字符串替换文件中的单词并处理缩进级别

时间:2017-04-22 20:46:20

标签: python indentation text-processing code-translation

所以我做了一个练习。我必须编写一个python脚本,用' .prog'查找实际文件夹中的所有文件。延期。 (这部分程序已经有效)。这个prog文件看起来像这样:

import sys

n = int(sys.argv[1]) ;print "Start of the program!"

LOOP i in range(1,n) [[print "The number:";print i]]

DECISION n < 5 [[print n ;print "smaller then 5"]]

输出应为:

import sys  

n = int(sys.argv[1]) 
print "Start of the program!"

for i in range(1,n) :
    print "The number:"
    print i

if n < 5 :
    print n 
    print "smaller then 5"

所以我必须将LOOP替换为for,将DECISION替换为if。它可以是&#39 ;;&#39;之前的空间,但它不能在它之后。 &#39; [[**]]&#39;总是包含python语句。 在for循环和if语句之后,命令总是必须在四个空格后开始。 这是我的代码:

#!/usr/bin/env python
# -*- coding: utf-8 -*-

def find():
import glob, os
os.chdir(os.getcwd())
for file in glob.glob("*.prog"):
    ProgToPy(file)


def  ProgToPy(f):
outname = f.replace("prog","py")
replacements = {'LOOP':'for',  'DECISION':'if', ' ;':'\n', ';':'\n    ', ' [[':' :\n    ', ']]':''}
with open(f) as infile, open(outname, 'w') as outfile:
    for line in infile:
        for src, target in replacements.iteritems():
            line = line.replace(src, target)
        outfile.write(line)

find()

我的输出看起来像这样的问题:

import sys

n = int(sys.argv[1])
print "Start of the program!"

for i in range(1,n) :
    print "The number:"
    print i

if n < 5 :
    print n
print "smaller then 5"

如果我在替换' ;':'\n '中加入这样的内容。第一次打印将在四个空格后开始。然后,创建的.py文件无法正常运行。

2 个答案:

答案 0 :(得分:0)

您可以使用正则表达式来解决您的问题。

import re
import glob, os

pattern = r'(.*)\[\[(.*)\]\]'
regex = re.compile(pattern)

def ProgToPy(f):
    outname = f.replace("prog","py")    
    replacements = {'LOOP':'for',  'DECISION':'if', ';': '\n\t'}

    with open(f) as infile, open(outname, 'w') as outfile:
        for line in infile:
            m = regex.match(line)

            if m:
                line = ''
                for matched_part in m.groups():
                    line += matched_part + '\n\t'

            for src, target in replacements.iteritems():
                line = line.replace(src, target)

            outfile.write(line)

os.chdir(os.getcwd())
for file in glob.glob("*.prog"):
    ProgToPy(file)

答案 1 :(得分:0)

由于分号根据其位置的不同而有所不同,因此您应该为每个状态编写单独的函数。 [[...]]表示Python中的块范围,因此我们将这些状态称为normal stateblock state

要控制状态,我们将使用布尔变量in_block并使用正则表达式来确定其值。

在这里,我将所有替换任务放在replaceTokens函数中。

def replaceTokens(statement, in_block=False):
    if in_block:
        statement = statement.replace(SEMI, NEWLINE+TABSPACE)
        statement = statement.replace(OPEN_BRACKETS, COLON+NEWLINE+TABSPACE)
    else:
        statement = statement.replace(SEMI, NEWLINE)
        statement = statement.replace(OPEN_BRACKETS, COLON+NEWLINE)

    statement = statement.replace(CLOSE_BRACKETS, NEWLINE)

    statement = statement.replace(LOOP, FOR)
    statement = statement.replace(DECISION, IF)

    return statement

上面的代码看起来很乏味,但如果你想要,你可以轻松地为此编写一个for循环。这里重要的一点就是我使用的是布尔变量in_block。这允许您根据双括号的存在来决定是否使用制表符跟随换行符。

要查找块范围内的语句,我使用正则表达式:

def progToPy(f):
    outname = f.replace("prog","py")
    rf = open(f, "r")
    text = rf.read()

    rf.close()

    block_regex = re.compile(r'\[\[.*\]\]')
    mo = block_regex.findall(text)

    for match in mo:
        statement = blockScope(match)
        text = text.replace(match, statement)

    text = replaceTokens(text)
    print(text)

blockScope函数使用in_block=True替换块范围内的语句,然后首先替换这些部分。然后,当我们在整个文档上调用replaceTokens时,块范围内的那些已被替换,因此不会受到第二次调用的影响。

def blockScope(block):
    statement = replaceTokens(block, in_block=True)
    return statement