У меня возникают проблемы при попытке получить набор похожих строк из набора текстовых (HTML) файлов с помощью регулярных выражений Python.Указанные файлы выглядят примерно так:
<!DOCTYPE html>
<html lang=fi>
<head>
<meta charset=UTF-8>
<title>Peruslaskutoimituksia</title>
<link rel=stylesheet type="text/css" href=
"https://math.tut.fi/mathcheck/mathcheck.css">
<script type="text/javascript" src=
"https://math.tut.fi/mathcheck/MathJax/MathJax.js?config=AM_HTMLorMML">
</script>
</head>
<body>
<h1>Peruslaskutoimituksia</h1>
<p>Kirjoita vastauksesi yhtäsuuruusmerkin jälkeen.
<form action="https://math.tut.fi/mathcheck/cgi-bin/mathcheck.out" method=post
target=_blank>
<table class=ifr>
<tr><td class=ifrl>
<p>1. Määritä luvun ` 9 ` käänteisluku.
<textarea name="hidden" style=display:none>
verbose_off
/* Tehtävä 1 */
arithmetic
f_nodes 4
1/( 9 )
</textarea>
<p><textarea rows=2 cols=30 autofocus name="exam">= </textarea>
<textarea name="hidden" style=display:none>end_of_answer</textarea>
<input type=submit formtarget=feedback1 value="submit, to the right">
</td><td class=ifrr>
<iframe name=feedback1 height=200></iframe></td></tr>
</table>
</form>
<form action="https://math.tut.fi/mathcheck/cgi-bin/mathcheck.out" method=post
target=_blank>
<table class=ifr>
<tr><td class=ifrl>
<p>2. Määritä luvun ` -4 ` vastaluku.
<textarea name="hidden" style=display:none>
verbose_off
/* Tehtävä 2 */
arithmetic
f_nodes 2
(-1)*( -4 )
</textarea>
<p><textarea rows=2 cols=30 name="exam">= </textarea>
<textarea name="hidden" style=display:none>end_of_answer</textarea>
<input type=submit formtarget=feedback2 value="submit, to the right">
</td><td class=ifrr>
<iframe name=feedback2 height=200></iframe></td></tr>
</table>
</form>
<form action="https://math.tut.fi/mathcheck/cgi-bin/mathcheck.out" method=post
target=_blank>
<table class=ifr>
<tr><td class=ifrl>
<p>3. Laske lausekkeen ` 7 /d^ 3 + 4 ` arvo, kun `d=3`. Anna vastaus
kokonaislukuna tai murtolukuna `a/b`, missä `a` ja `b` ovat kokonaislukuja.
<textarea name="hidden" style=display:none>
verbose_off
/* Tehtävä 3 */
arithmetic
f_nodes 3
7 /3^ 3 + 4
</textarea>
<p><textarea rows=2 cols=30 name="exam">= </textarea>
<textarea name="hidden" style=display:none>end_of_answer</textarea>
<input type=submit formtarget=feedback3 value="submit, to the right">
</td><td class=ifrr>
<iframe name=feedback3 height=200></iframe></td></tr>
</table>
</form>
<form action="https://math.tut.fi/mathcheck/cgi-bin/mathcheck.out" method=post
target=_blank>
<table class=ifr>
<tr><td class=ifrl>
<p>4. Laske lausekkeen `x^ 4 + x^ 3 ` arvo, kun `x = 3`.
<textarea name="hidden" style=display:none>
verbose_off
/* Tehtävä 4 */
arithmetic
f_nodes 1
3^ 4 + 3^ 3
</textarea>
<p><textarea rows=2 cols=30 name="exam">= </textarea>
<textarea name="hidden" style=display:none>end_of_answer</textarea>
<input type=submit formtarget=feedback4 value="submit, to the right">
</td><td class=ifrr>
<iframe name=feedback4 height=200></iframe></td></tr>
</table>
</form>
<form action="https://math.tut.fi/mathcheck/cgi-bin/mathcheck.out" method=post
target=_blank>
<table class=ifr>
<tr><td class=ifrl>
<p>5. Laske lausekkeen `( 8 )/( 5 ): ( 2 )/( 3 )` arvo murtolukuna `a/b`, missä
`a` ja `b` ovat kokonaislukuja.
<textarea name="hidden" style=display:none>
verbose_off
/* Tehtävä 5 */
arithmetic
f_nodes 3
(( 8 )/( 5 ))/(( 2 )/( 3 ))
</textarea>
<p><textarea rows=2 cols=30 name="exam">= </textarea>
<textarea name="hidden" style=display:none>end_of_answer</textarea>
<input type=submit formtarget=feedback5 value="submit, to the right">
</td><td class=ifrr>
<iframe name=feedback5 height=200></iframe></td></tr>
</table>
</form>
<hr>
<p class=unimp>This file was generated 2018-07-06 11:23:11 UTC.
</body>
</html>
Конкретные строки, которые я пытаюсь получить, - это строки, содержащиеся между тегами
<p>(some number). ...</textarea>,
, например
<p>1. Määritä luvun ` 9 ` käänteisluku.
<textarea name="hidden" style=display:none>
verbose_off
/* Tehtävä 1 */
arithmetic
f_nodes 4
1/( 9 )
</textarea>
Однако, вызов функции Python regex findall
следующим образом
"""
Reading the assignments into memory from the produced HTML-files
"""
htmlDirEntries = sorted([filename for filename in os.listdir("./HTMLfiles") if filename.endswith(".html")])
# print(htmlDirEntries)
HTMLdict = {}
for filename in htmlDirEntries:
print(f"Copying contents of {filename}...")
with open(f"./HTMLfiles/{filename}", 'r') as f:
filecontents = f.read()
HTMLdict[filename] = filecontents
print("Done.")
print()
print("Looking for and collecting assignments...")
print()
for filename in HTMLdict:
print(filename)
assignments = re.findall("<p>\d.+.*</textarea>", HTMLdict[filename], re.DOTALL)
i = 1
for assignment in assignments:
print(f"Assignment {i}")
i += 1
print(assignment)
print("Done.")
не возвращает желаемый результат, который должен быть списком строк, выглядящих примерно так:
'<p>1. Määritä luvun ` 7 ` käänteisluku.\n\n<textarea name="hidden" style=display:none>\nverbose_off\n/* Tehtävä 1 */\narithmetic\nf_nodes 4\n1/( 7 )\n</textarea>'
Вместо этого возвращается содержимое всего файла, начиная с первого <p>1. ...
.Я предполагаю, что мое использование re.findall
неверно.
Интересно, почему метод findall
не возвращает строку, заканчивающуюся на первый </textarea>
после начального <p>
?Что я здесь не так делаю?Моим первым предположением было бы посмотреть на регулярное выражение, данное findall
, а именно: "<p>\d.+.*</textarea>"
...
РЕДАКТИРОВАТЬ:
Следующее выражение возвращает то, что я хочу, хотя это не такt работает во всех случаях:
assignments = re.findall(r"<p>\d+.+\n\n.+\n.+\n.+\n.+\n.+\n.+\n</textarea>", HTMLdict[filename])
С некоторыми файлами это возвращает пустой список, хотя я почти уверен, что они имеют одинаковый формат.
EDIT2
Оказывается, файлы не были в том же формате.В некоторых файлах есть дополнительные символы новой строки между начальным <p>
-tag и <textarea...