Python,读/写文档时未知跳过

2024-09-30 14:16:06 发布

您现在位置:Python中文网/ 问答频道 /正文

所以我使用python来帮助将文本文件转换成xml。下面的文本文档的Somme。你知道吗

:
Breakfast Breads

Gluten Free Nut Loaf
Makes 1 loaf

150 g (51/2 oz./11/2 cups) 
almond meal
30 g (1 oz./1/4 cup)
walnuts, coarsely chopped
1/4 teaspoon 
gluten-free baking powder

我不确定这是否可以复制,因为它可能是文件本身中的一个幽灵。但如果你能试试,那就太好了。你知道吗

为了说明当前的步骤,我的代码很初级,找冒号,它知道下一行是一个普通的类别,然后切换一个step变量。然后,下一步将跳过空行“\r\n”,直到找到一个非空行,该行用其名称标识单个配方的开头。循环的下一行,如果是空的change step,则为服务大小编写xml,然后更改step。你知道吗

我们到了配料步骤。所以奇数行是数量,偶数行是实际成分。你知道吗

if step == 2:
    if line == empty: 
        continue
    else:
        xmlMenu.write("\n\t<ingredients>") 
        qty = line
        qtyXML = ("\n\t\t<qty>\n\t\t\t" + qty + "\t\t</qty>")
        xmlMenu.write(qtyXML)
        step = 2.2
        continue

if step == 2.2:
        if menu.next() == empty:
            ingredient = line
            pass
            ingredientXML = ("\n\t\t<ingredient>\n\t\t\t" + ingredient + "\t\t</ingredient>\n\t</ingredients>")
            xmlMenu.write(ingredientXML)
            step = 3
            continue

        else:
            ingredient = line
            ingredientXML = ("\n\t\t<ingredient>\n\t\t\t" + ingredient + "\t\t</ingredient>\n\t</ingredients>")
            xmlMenu.write(ingredientXML)
            step = 2
            continue

我的问题是,当它到达第二组数量/配料时,它似乎跳过了杏仁粉的数量,因此把整个xml文件搞砸了。你知道吗

<recipe>
    <category>
        Breakfast Breads
    </category>
    <name>
        Gluten Free Nut Loaf
    </name>
    <servings>
        Makes 1 loaf
    </servings>
    <ingredients>
        <qty>
            150 g (51/2 oz./11/2 cups) 
        </qty>
        <ingredient>
            almond meal
        </ingredient>
    </ingredients>
    <ingredients>
        <qty>
            walnuts, coarsely chopped
        </qty>
        <ingredient>
            1/4 teaspoon 
        </ingredient>
    </ingredients>

有人认为我的代码在什么地方是垃圾吗?另外,有什么更好的方法来做这件事的建议。我还是初级编程。你知道吗

//编辑以获取更多代码。当代码开始一个新的配方时,它在集合的末尾仍在工作。你知道吗

empty = '\r\n'
colon = ':'
new_contents = []

category = ''
categoryXML = ''

recipe = ''
recipeXML = ''

servings = ''
servingsXML = ''

ingrediants = ''
ingrediantsXML = ''

ingredient = ''
ingredientXML = ''
qty = ''
qtyXML = ''

instructions = ''
instructionsXML = ''

intNo = ''
intNoXML = ''
instruction = ''
instructionXML = ''

step = ''

x = 0

menu = open("menuTextFormat.txt", 'r')
xmlMenu = open('menuTextXML.txt', 'w')

for line in menu:
    # if not line.strip():
    #    continue
    #else:
    #     new_contents.append(line)
    if colon in line:
        step = 0
        continue

    if step == 0: 
        if not line:
            continue 
        else:       
            category = line
            categoryXML = "<recipe>\n\t<category>\n\t\t" + category + "\t</category>"
            xmlMenu.write(categoryXML)    
            step = 1            
            continue

    if step == 1:
        if line == empty:
            continue 
        else:
            recipe = line
            recipeXML = ("\n\t<name>\n\t\t" + recipe + "\t</name>")
            xmlMenu.write(recipeXML)
            step = 12
            continue

    if step == 12:
        if line == empty:
            step = 2
            continue
        else: 
            servings = line
            servingsXML = ("\n\t<servings>\n\t\t" + servings + "\t</servings>")
            xmlMenu.write(servingsXML)
            step = 2

            continue

    if step == 2:
        if line == empty: 
            continue
        else:
            xmlMenu.write("\n\t<ingredients>") 
            qty = line
            qtyXML = ("\n\t\t<qty>\n\t\t\t" + qty + "\t\t</qty>")
            xmlMenu.write(qtyXML)
            step = 22
            continue

    if step == 22:
            if menu.next() == empty:
                ingredient = line
                ingredientXML = ("\n\t\t<ingredient>\n\t\t\t" + ingredient + "\t\t</ingredient>\n\t</ingredients>")
                xmlMenu.write(ingredientXML)
                step = 3
                continue

            else:
                ingredient = line
                ingredientXML = ("\n\t\t<ingredient>\n\t\t\t" + ingredient + "\t\t</ingredient>\n\t</ingredients>")
                xmlMenu.write(ingredientXML)
                step = 2
                continue

    if step == 3:
        if line == empty:
            continue 
        else:
            x += 1
            intNoXML = ("\n\t\t<id>\n\t\t\t" + str(x) + "\n\t\t</id>")
            xmlMenu.write(intNoXML)
            instruction = line
            instructionXML = ("\n\t\t<instruction>\n\t\t\t" + instruction + "\t\t</instruction>")
            xmlMenu.write(instructionXML)
            if menu.next() == empty:
                step = 4
                continue
            else:
                continue
            continue

    if step == 4:
        if not menu.next():
            break
        else:
            step = 1
            continue


    #print line

#xmlMenu.write("".join(new_contents))


xmlMenu.close()
menu.close()


:
Breakfast Breads

Gluten Free Nut Loaf
Makes 1 loaf

150 g (51/2 oz./11/2 cups) 
almond meal
30 g (1 oz./1/4 cup)
walnuts, coarsely chopped
1/4 teaspoon 
gluten-free baking powder
1 teaspoon 
ground cinnamon
95 g (31/4 oz./3/4 cup) 
arrowroot (tapioca) flour
1/2 teaspoon 
sea salt
3 
organic eggs
1/2 teaspoon 
stevia powder
3 tablespoons 
grape seed oil
2 tablespoons 
coconut Milk
1 teaspoon 
apple cider vinegar

Preheat the oven to 180∫C (350∫F/Gas 4). 
Grease a 20 x 9 cm (8 x 31/2 inch) loaf (bar) tin.
Put the almond meal, walnuts, baking powder, cinnamon, arrowroot flour and salt in a large bowl and mix well with a wooden spoon. 
Crack the eggs into a separate bowl and whisk using an electric mixer until pale and fluffy, about 11/2 minutes. 
Add the stevia, grape seed oil, coconut milk and vinegar and mix gently. 
Pour the mixture into the dry ingredients and stir to combine. 
Spoon the mixture into the greased tin and bake for about 40 minutes, or until a skewer inserted in the centre of the loaf comes out clean. 
Remove the bread from the oven and leave to cool in the tin for a few minutes, before turning out onto a wire rack to cool completely. 
Enjoy the bread melt-in-the-mouth warm, or at room temperature with your favourite topping.  

Basic Gluten Free Loaf

2Ω cups 
blanched almond flour
Ω teaspoon 
baking soda
1 tsp. 
bicarbonate of soda
3 
eggs beaten
1 tsp. 
stevia powder
Ω teaspoon 
apple cider vinegar
!!
Pinch sea salt

Preheat oven to 250 degrees Celsius
Grease a small loaf pan
Combine dry ingredients in a bowl
In a separate bowl place eggs and apple cider vinegar
Spoon the mixture into loaf pan
Bake for 50 mins until set
Cool on wire rack
Slice when cool

更多的数据。你知道吗


Tags: andtheifsteplineelsewriteempty
2条回答

你会注意到一些事情……
1我删除了很多你在循环之前列出的变量。你不需要在循环之前列出它们。
2我把它换成了while循环。我个人喜欢一行一行读东西的吸引力
三。我在“名称”部分中写了类别,这是因为新配方开始时,类别并不总是列出的,所以我认为最好使用最后一个已知的类别,并将其插入每个新配方的前面。
4您的份量并不总是列出来的,所以我冒昧地在那里添加了一个复选框,以便它会返回“未列出来的份量”以防万一。
5我在配料上打了个圈。你知道吗

备注:
1由于每个if step == 1 and line:中都有and line,所有的空行都被完全忽略。变量line从所有行返回中剥离,因此while循环跳过所有新行。这些步骤只是确保在跳过每一个空行之后我们所做的事情是正确的。
2坚果面包听起来很好吃

代码:

category=''
step=0

menu = open("menuTextFormat.txt", 'r')
xml = open('menuTextXML.txt', 'w')

xml.write("<recipe>\n")

while 1:
    line = menu.readline()
    if not line:
        break

    #after checking for EOF, remove \n
    line = line.rstrip()

    #category
    if ":" in line:
        #set category as next line
        category = menu.readline().rstrip()
        step=1
        continue

    #name & servings
    if step == 1 and line:
        #write category
        xml.write("\t<category>\n\t\t" + category + "\n\t</category>\n")
        #write name
        xml.write("\t<name>\n\t\t" + line + "\n\t</name>\n")

        #check for serving size
        servings = menu.readline().rstrip()
        if not servings:
            xml.write("\t<servings>\n\t\tno serving size listed\n\t</servings>\n")
        else:
            xml.write("\t<servings>\n\t\t" + servings + "\n\t</servings>\n")

        step=2
        continue

    #ingredients
    if step == 2 and line:
        #write first ingredient, then loop for rest
        xml.write("\t<qty>\n\t\t" + line + "\n\t</qty>\n")
        xml.write("\t<ingredient>\n\t\t" + menu.readline().rstrip() + "\n\t</ingredient>\n")

        #loop for incredients
        while 1:
            qty = menu.readline().rstrip()
            #no more incredients, break loop
            if not qty:
                break

            xml.write("\t<qty>\n\t\t" + qty + "\n\t</qty>\n")
            xml.write("\t<ingredient>\n\t\t" + menu.readline().rstrip() + "\n\t</ingredient>\n")

        step=3
        continue

    #procedure
    if step == 3 and line:
        #write first step, then loop for rest
        xml.write("\t<procedure>\n")
        xml.write("\t\t<step>\n\t\t\t" + line + "\n\t\t</step>\n")

        #loop for steps
        while 1:
            step = menu.readline().rstrip()
            #no more steps, break loop
            if not step:
                break

            xml.write("\t\t<step>\n\t\t\t" + step + "\n\t\t</step>\n")

        xml.write("\t</procedure>\n")

        step=1
        continue

xml.write("</recipe>")
menu.close()
xml.close()

输出:

<recipe>
    <category>
        Breakfast Breads
    </category>
    <name>
        Gluten Free Nut Loaf
    </name>
    <servings>
        Makes 1 loaf
    </servings>
    <qty>
        150 g (51/2 oz./11/2 cups)
    </qty>
    <ingredient>
        almond meal
    </ingredient>
    <qty>
        30 g (1 oz./1/4 cup)
    </qty>
    <ingredient>
        walnuts, coarsely chopped
    </ingredient>
    <qty>
        1/4 teaspoon
    </qty>
    <ingredient>
        gluten-free baking powder
    </ingredient>
    <qty>
        1 teaspoon
    </qty>
    <ingredient>
        ground cinnamon
    </ingredient>
    <qty>
        95 g (31/4 oz./3/4 cup)
    </qty>
    <ingredient>
        arrowroot (tapioca) flour
    </ingredient>
    <qty>
        1/2 teaspoon
    </qty>
    <ingredient>
        sea salt
    </ingredient>
    <qty>
        3
    </qty>
    <ingredient>
        organic eggs
    </ingredient>
    <qty>
        1/2 teaspoon
    </qty>
    <ingredient>
        stevia powder
    </ingredient>
    <qty>
        3 tablespoons
    </qty>
    <ingredient>
        grape seed oil
    </ingredient>
    <qty>
        2 tablespoons
    </qty>
    <ingredient>
        coconut Milk
    </ingredient>
    <qty>
        1 teaspoon
    </qty>
    <ingredient>
        apple cider vinegar
    </ingredient>
    <procedure>
        <step>
            Preheat the oven to 180∫C (350∫F/Gas 4).
        </step>
        <step>
            Grease a 20 x 9 cm (8 x 31/2 inch) loaf (bar) tin.
        </step>
        <step>
            Put the almond meal, walnuts, baking powder, cinnamon, arrowroot flour and salt in a large bowl and mix well with a wooden spoon.
        </step>
        <step>
            Crack the eggs into a separate bowl and whisk using an electric mixer until pale and fluffy, about 11/2 minutes.
        </step>
        <step>
            Add the stevia, grape seed oil, coconut milk and vinegar and mix gently.
        </step>
        <step>
            Pour the mixture into the dry ingredients and stir to combine.
        </step>
        <step>
            Spoon the mixture into the greased tin and bake for about 40 minutes, or until a skewer inserted in the centre of the loaf comes out clean.
        </step>
        <step>
            Remove the bread from the oven and leave to cool in the tin for a few minutes, before turning out onto a wire rack to cool completely.
        </step>
        <step>
            Enjoy the bread melt-in-the-mouth warm, or at room temperature with your favourite topping.
        </step>
    </procedure>
    <category>
        Breakfast Breads
    </category>
    <name>
        Basic Gluten Free Loaf
    </name>
    <servings>
        no serving size listed
    </servings>
    <qty>
        2Ω cups
    </qty>
    <ingredient>
        blanched almond flour
    </ingredient>
    <qty>
        Ω teaspoon
    </qty>
    <ingredient>
        baking soda
    </ingredient>
    <qty>
        1 tsp.
    </qty>
    <ingredient>
        bicarbonate of soda
    </ingredient>
    <qty>
        3
    </qty>
    <ingredient>
        eggs beaten
    </ingredient>
    <qty>
        1 tsp.
    </qty>
    <ingredient>
        stevia powder
    </ingredient>
    <qty>
        Ω teaspoon
    </qty>
    <ingredient>
        apple cider vinegar
    </ingredient>
    <qty>
        !!
    </qty>
    <ingredient>
        Pinch sea salt
    </ingredient>
    <procedure>
        <step>
            Preheat oven to 250 degrees Celsius
        </step>
        <step>
            Grease a small loaf pan
        </step>
        <step>
            Combine dry ingredients in a bowl
        </step>
        <step>
            In a separate bowl place eggs and apple cider vinegar
        </step>
        <step>
            Spoon the mixture into loaf pan
        </step>
        <step>
            Bake for 50 mins until set
        </step>
        <step>
            Cool on wire rack
        </step>
        <step>
            Slice when cool
        </step>
    </procedure>
</recipe>

如果将代码划分为多个函数,每个函数只负责识别一个小功能,例如:

def parse_next_receipe(lines, pos=0):
    while 1:
        if pos >= len(lines):
            break

        line = lines[pos]
        if line.strip() == ':':
            pos, receipe = parse_receipe(lines, pos)
            yield receipe  # or write it directly to the xml file...
        else:
            pos += 1

def parse_receipe(lines, pos):
    pos, name = parse_name(lines, pos)
    pos, description = parse_description(lines, pos)
    ingredients = []

    while 1:
        pos, ingredient = parse_ingredient(lines, pos)
        if pos == -1:
            break
        else:
            ingredients.append(ingredient)

    return (name, description, ingredients)


def parse_name(lines, pos): ...

def parse_description(lines, pos): ...

def parse_ingredient(lines, pos):
    try:
        pos, quantity = parse_quantity(lines, pos)
        pos, ingredient = parse_ingredientname(lines, pos)
    except ValueError:
        return -1, None

def parse_quantity(lines, pos):
    line = lines[pos]
    if line[0] in '0123456789':
        # line starts with a number
        return pos + 1, line
    raise ValueError("Line %r doesn't contain a quantity" % line)

def parse_ingredientname(lines, pos):
    line = lines[pos]
    if line:
        # any non-empty line is ok as an ingredient name
        return pos + 1, line
    raise ValueError("Expected an ingredient name, found blank line, lineno=%d" % pos)

这称为递归下降解析。你知道吗

在本例中,每个函数都接受一个pos,这是它应该开始查找的行号,并返回要查找的“next”行+它找到的值。你知道吗

我使用了两种不同的方法来指示解析错误:返回-1作为位置(返回None作为值),或者引发异常。任何一个都是有用的。你知道吗

相关问题 更多 >

    热门问题