Синтаксис вложенного цикла на страницах сервера Python - PullRequest
1 голос
/ 11 марта 2009

Я просто пытаюсь написать небольшую веб-страницу, которая может анализировать некоторый текст с помощью регулярного выражения и возвращать полученные совпадения в таблицу. Это первый раз, когда я использовал python для веб-разработки, и я должен сказать, что это выглядит грязно.

Мой вопрос: почему я получаю вывод только для последнего совпадения в моем наборе данных? Я полагаю, что это должно быть потому, что вложенные циклы не отформатированы правильно.

Вот данные, которые я предоставляю:

groups - это просто id, соответствующий группе регулярных выражений, и это имя для предоставления заголовка таблицы.

шаблон это что-то вроде:

(\d+)\s(\S+)\s(\S+)$

и данные:

12345 SOME USER
09876 SOMEONE ELSE
54678 ANOTHER USER

Моя простая страница:

<%
import re
pattern = form['pattern']
p = re.compile(pattern)
data = form['data']

matches = p.finditer(data)

lines = form['groups'].split("\n")
groupids ={}
for line in lines:
  key, val = line.split(' ')
  groupids[int(key.strip())] = val.strip()

%>
<html>
<table style="border-width:1px;border-style:solid;width:60%;">
<tr>
<%
for k,v in groupids.iteritems():%>
<th style="width:30px;text-align:center"><%= v %></th>
<%
# end
%>
</tr>
<%
for match in matches:
  #begin
%><tr>
<%
for i in range(1, len(match.groups())+1):
  #begin
%>
  <td style="border-style:solid;border-width:1px;border-spacing:0px;text-align:center;"><%= match.group(i) %></td>
<%
  #end
# end
%>
</tr>

</table>
</html>

Редактировать

Ниже приведен тест, который я провел

Код:

import re
pattern = "(\d\d\d\d\d)\s(\S+)\s(\S+)"

p = re.compile(pattern)

data = """12345 TESTS USERS
34567 TESTS USERS
56789 TESTS USERS"""

groups = """1 PIN
2 FNAME
3 LNAME"""

matches = p.finditer(data)

lines = groups.split("\n")

print lines
groupids ={}
for line in lines:
  key, val = line.split(' ')
  groupids[int(key.strip())] = val.strip()


for k,v in groupids.iteritems():
  print "%s\t" % v,
print ''

for match in matches:
  for i in range(1, len(match.groups())+1):
    print "%s\t" % match.group(i),
  print ''

Вывод:

PIN     FNAME   LNAME
12345   TESTS   USERS
34567   TESTS   USERS
56789   TESTS   USERS

Ответы [ 2 ]

1 голос
/ 11 марта 2009
<%
for match in matches:
  #begin
%><tr>
<%
for i in range(1, len(match.groups())+1):
  #begin
%>
  <td style="border-style:solid;border-width:1px;border-spacing:0px;text-align:center;"><%= match.group(i) %></td>
<%
  #end
# end
%>

Да, у вас там нет вложенного цикла. Вместо этого у вас есть цикл над matches, который выдает «

\ n», а затем второй цикл над range(...), который запускается только после того, как первый завершится. Второе не находится внутри первого, потому что оно не имеет отступа, чтобы сказать это.

Из документа я думаю , что вам нужно сказать:

<%
for match in matches:
    # begin
%><tr><%
    for group in match.groups():
        # begin
%><td style="border-style:solid;border-width:1px;border-spacing:0px;text-align:center;"><%= group %></td><%
    # end
%></tr><%
# end
%>

Но я могу только согласиться с вашим «грязным» комментарием: если PSP требует, чтобы вы пытали отступы вашего HTML, чтобы он соответствовал структуре вашего Python, вот так, это действительно делает его неправильно, и вы должны искать другой менее ужасный синтаксис шаблонов. Существует множество языков шаблонов для Python, которые имеют более разумный синтаксис для управляющих структур. В качестве примера, в том, который я использую выше, будет выглядеть так:

<px:for item="match" in="matches"><tr>
    <px:for item="group" in="match.groups()">
        <td style="border-style:solid;border-width:1px;border-spacing:0px;text-align:center;">
            <?_ group ?>
        </td>
    </px:for>
</tr></px:for>
0 голосов
/ 11 марта 2009

Я не уверен насчет взаимодействия с движком шаблонов, но python ожидает, что внутренний цикл будет иметь отступ под содержащим циклом.

Попробуйте отформатировать его таким образом и посмотрите, работает ли он.

<%
for match in matches:
    %><tr><%
    for i in range(1, len(match.groups())+1):
        %><td style="border-style:solid;border-width:1px;border-spacing:0px;text-align:center;"><%= match.group(i) %></td><%
%>

Или некоторые такие. Выше приведено «IndentationError: unindent не соответствует ни одному внешнему уровню отступа», поэтому попробуйте:

<%
for match in matches:
    %><tr><%
    for i in range(1, len(match.groups())+1):
        %><td style="border-style:solid;border-width:1px;border-spacing:0px;text-align:center;"><%= match.group(i) %></td><%

%>

или

<%
for match in matches:
    %><tr><%
    for i in range(1, len(match.groups())+1):
        %><td style="border-style:solid;border-width:1px;border-spacing:0px;text-align:center;"><%= match.group(i) %></td><%
pass
%>

или некоторая комбинация. Ваша проблема заключается в указании Python, где заканчивается цикл. Чтобы сделать это, вы должны найти способ заставить шаблонизатор создавать правильный питон с правильным отступом.

Кроме того, если вы можете получить сгенерированный код, вы можете разделить проблему пополам: сначала поработайте с сгенерированным кодом, чтобы выяснить, что примет python, а затем поработайте с шаблоном, чтобы получить его.

...