简体   繁体   English

使用Python正则表达式从.tex文档中提取文本

[英]Extracting text from a .tex document with Python regular expressions

I'm attemping to retrieve a bunch a text from a LaTeX file, that consists of blocks like 我正在尝试从LaTeX文件中检索一堆文本,该文本由诸如

\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. 使用re.findall ,我想在每个命令中紧跟\\lh之后访问3个字母的代码以及命令的内容或定义,这意味着在命令名定义之后的大括号之间包含整个文本块。

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). 解析3个字母的代码不是问题,但\\newcommand{\\lhaac}{<contents>}证明很难获得\\newcommand{\\lhaac}{<contents>}所有内容的访问权限,因为LaTeX源代码可能包含花括号和反斜杠以及其他讨厌的东西,这使得很难表达我要访问的内容实际上是如何结束的(因为大括号会结束命令定义)。 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. 在最后一种情况下,我认为我已经介绍了普通文本,数学(内联$<math here>$和显示$$<math here>$$ )以及命令( \\<command name>[<optional argument>]{<mandatory argument>} ),带或不带参数。 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. 根据re.findall文档 ,它应该返回一个元组列表(因为我在正则表达式中有多个捕获组),每个元组的第三个元素是三字母代码,第二个元素是命令内容。 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

")]

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})$

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM