Reputation: 1603
I'm attemping to retrieve a bunch a text from a LaTeX file, that consists of blocks like
\newcommand{\lhaac}{% 2
Olkoot tapahtumat A = 'kortti on musta', B = 'kortti on hertta' ja
C = 'kortti on kuvakortti tai ässä'. Lausu seuraavat tapahtumat joukkojen A,B ja C sekä joukko-operaatioiden avulla\\% ja laske todennäköisyydet \\
\textbf{a)} Kortti on musta kuvakortti tai musta ässä\\
\textbf{b)} Kortti on ruutu\\
\textbf{c)} Kortti ei ole ruutu, mutta se on kuva tai ässä\\
\textbf{d)} Kortti on joko punainen tai se on arvoltaan 2-10, mutta ei molempia
}
%__________
\newcommand{\lhaacv}{%
a) Kortti on musta kuvakortti tai musta ässä = Kortti on musta ja kortti on kuvakortti tai ässä: $A\cap C$,\\
b) Kortti on ruutu = kortti ei musta ja ei hertta: $\overline{A}\cap\overline{B} = \overline{A\cup B}$\\
c) (Kortti on musta tai hertta) ja kortti on kuva tai ässä:\\ $(A\cup B)\cap C = (A\cap C)\cup (B\cap C)$ \\
d) Kortti on punainen kuvakortti tai musta pikkukortti:\\ $(\overline{A}\cap C)\cup (A\cap \overline{C}) = (\overline{A}\cup \overline{C})\backslash (\overline{A}\cap \overline{C})$
}
Using re.findall
, I would like to gain access to the 3-letter code immediately succeeding \lh
in each command, and the command contents or definitions, meaning the entire blocks of text contained between the braces after the command name definition.
Parsing the 3-letter code is not an issue, but simply gaining access to all of the contents of \newcommand{\lhaac}{<contents>}
is proving to be difficult, since LaTeX source can contain braces and backslashes and other nasty things, making it difficult to express how contents I want to access actually end (because a brace ends a command definition). The comment lines
%__________
can not be trusted to exist after every command.
I've tried this and this, for starters. In the first case, the matching stops after the first }
encountered, while in the second example pretty much everything after the beginning {
is matched, just as expected. Attempting something more complicated like this seems to work on a simple test case, but entering an actual block found in the file produces no match.
I'm therefore asking for help in cracking this puzzle. I can't seem to see what I'm missing here. In the last case, I think I've covered normal text, math (both inline $<math here>$
and display $$<math here>$$
), and commands (\<command name>[<optional argument>]{<mandatory argument>}
) with and without arguments. Environments, such as
\begin{<environment name>}[<optional argument>]{<mandatory argument>}
<contents>
\end{<environment name>}
are still missing, but those can be easily covered later.
As per re.findall
documentation, it should return a list of tuples (since I have multiple capturing groups in the regex), with the 3-letter code as the first and the command contents as the second element of each tuple. In this case the first tuple (contained in a list) returned would be
[("aac", "% 2
Olkoot tapahtumat A = 'kortti on musta', B = 'kortti on hertta' ja
C = 'kortti on kuvakortti tai ässä'. Lausu seuraavat tapahtumat joukkojen A,B ja C sekä joukko-operaatioiden avulla\\% ja laske todennäköisyydet \\
\textbf{a)} Kortti on musta kuvakortti tai musta ässä\\
\textbf{b)} Kortti on ruutu\\
\textbf{c)} Kortti ei ole ruutu, mutta se on kuva tai ässä\\
\textbf{d)} Kortti on joko punainen tai se on arvoltaan 2-10, mutta ei molempia
")]
Upvotes: 0
Views: 129
Reputation: 5730
Here You go:
=^..^=
import re
raw_string = """\newcommand{\lhaac}{% 2
Olkoot tapahtumat A = 'kortti on musta', B = 'kortti on hertta' ja
C = 'kortti on kuvakortti tai ässä'. Lausu seuraavat tapahtumat joukkojen A,B ja C sekä joukko-operaatioiden avulla\\% ja laske todennäköisyydet \\
\textbf{a)} Kortti on musta kuvakortti tai musta ässä\\
\textbf{b)} Kortti on ruutu\\
\textbf{c)} Kortti ei ole ruutu, mutta se on kuva tai ässä\\
\textbf{d)} Kortti on joko punainen tai se on arvoltaan 2-10, mutta ei molempia
}
%__________
\newcommand{\lhaacv}{%
a) Kortti on musta kuvakortti tai musta ässä = Kortti on musta ja kortti on kuvakortti tai ässä: $A\cap C$,\\
b) Kortti on ruutu = kortti ei musta ja ei hertta: $\overline{A}\cap\overline{B} = \overline{A\cup B}$\\
c) (Kortti on musta tai hertta) ja kortti on kuva tai ässä:\\ $(A\cup B)\cap C = (A\cap C)\cup (B\cap C)$ \\
d) Kortti on punainen kuvakortti tai musta pikkukortti:\\ $(\overline{A}\cap C)\cup (A\cap \overline{C}) = (\overline{A}\cup \overline{C})\backslash (\overline{A}\cap \overline{C})$
}
%__________
"""
remove_command = re.sub(r'\newcommand{\\', '', raw_string)
codes = re.findall('lh\w+', remove_command)
part_1 = []
for item in codes:
part_1.append(item[2::])
result2 = re.findall(r'{.*?}\n%_+', remove_command, re.DOTALL)
part_2 = []
for item in result2:
clean_1 = re.sub(r'{%', '', item)
clean_2 = re.sub(r'\n}\n%_+', '', clean_1)
part_2.append(clean_2)
result = zip(part_1, part_2)
Output:
aac
2
Olkoot tapahtumat A = 'kortti on musta', B = 'kortti on hertta' ja
C = 'kortti on kuvakortti tai ässä'. Lausu seuraavat tapahtumat joukkojen A,B ja C sekä joukko-operaatioiden avulla\% ja laske todennäköisyydet \
extbf{a)} Kortti on musta kuvakortti tai musta ässä\
extbf{b)} Kortti on ruutu\
extbf{c)} Kortti ei ole ruutu, mutta se on kuva tai ässä\
extbf{d)} Kortti on joko punainen tai se on arvoltaan 2-10, mutta ei molempia
------------------------------------------------------------------------------------------------------------------------------------------------------
aacv
a) Kortti on musta kuvakortti tai musta ässä = Kortti on musta ja kortti on kuvakortti tai ässä: $A\cap C$,\
b) Kortti on ruutu = kortti ei musta ja ei hertta: $\overline{A}\cap\overline{B} = \overline{A\cup B}$\
c) (Kortti on musta tai hertta) ja kortti on kuva tai ässä:\ $(A\cup B)\cap C = (A\cap C)\cup (B\cap C)$ \
d) Kortti on punainen kuvakortti tai musta pikkukortti:\ $(\overline{A}\cap C)\cup (A\cap \overline{C}) = (\overline{A}\cup \overline{C}ackslash (\overline{A}\cap \overline{C})$
Upvotes: 1