正则表达式如何获得中间字符串

时间:2013-01-26 01:08:36

标签: python regex

我想搜索某个字符串之间出现的字符串。例如,

\start

\problem{number}
\subproblem{number}

/* strings that I want to get */

\subproblem{number}

/* strings that I want to get */

\problem{number}
\subproblem{number}
       ...
       ...
\end

更具体地说,我想得到问题编号和子问题编号以及字符串之间的答案。

我有点想出像

这样的表达方式
'(\\problem{(.*?)}\n)? \\subproblem{(.*?)} (.*?) (\\problem|\\subproblem|\\end)'

但它似乎无法正常工作。这个表达有什么问题?

3 个答案:

答案 0 :(得分:2)

TeX非常复杂,我不确定使用正则表达式解析它的感觉。

那就是说,你的正则表达式有两个问题:

  • 您正在使用空格字符,您应该只使用所有空格
  • 你需要为你的最后一组使用一个先行断言,这样它就不会被吃掉(因为你需要在下一次正则表达式的开头匹配它)

尝试一下:

>>> v
'\\start\n\n\\problem{number}\n\\subproblem{number}\n\n/* strings that I want to get */\n\n\\subproblem{number}\n\n/* strings that I want to get */\n\n\\problem{number}\n\\subproblem{number}\n       ...\n       ...\n\\end\n'
>>> re.findall(r'(?:\\problem{(.*?)})?\s*\\subproblem{(.*?)}\s*(.*?)\s*(?=\\problem{|\\subproblem{|\\end)', v, re.DOTALL)
[('number', 'number', '/* strings that I want to get */'), ('', 'number', '/* strings that I want to get */'), ('number', 'number', '...\n       ...')]

答案 1 :(得分:2)

这一个:

(?:\\problem\{(.*?)\}\n)?\\subproblem\{(.*?)\}\n+(.*?)\n+(?=\\problem|\\subproblem|\\end)

为我返回三场比赛:

匹配1:

group 1: "number"
group 2: "number"
group 3: "/* strings that I want to get */"

比赛2:

group 1: null
group 2: "number"
group 3: "/* strings that I want to get */"

比赛3:

group 1: "number"
group 2: "number"
group 3: "       ...\n       ..."

但是我宁愿分两步解析它。

首先使用以下方法查找问题编号(组1)和内容(组2):

\\problem\{(.*?)\}\n(.+?)\\end

然后使用以下内容查找该内容中的子问题编号(第1组)和内容(第2组):

\\subproblem\{(.*?)\}\n+(.*?)\n+(?=\\problem|\\subproblem|\\end)

答案 2 :(得分:2)

如果问题确实是“这个表达有什么问题?”,这就是答案:

  • 您正在尝试将换行符与.*?匹配。您需要(?s)才能工作。
  • 正则表达式中间有明确的空格和换行符,源文本中没有任何相应的字符。您需要(?x)才能工作。

这可能不是所有表达式错误。但只是添加(?sx),将其转换为原始字符串(因为我不相信自己可以正确混合Python引用和正则引用),并删除\n给我这个:

r'(?sx)(\\problem{(.*?)}? \\subproblem{(.*?)} (.*?)) (\\problem|\\subproblem|\\end)'

返回2个匹配而不是0,这可能是你的正则表达式的最小变化。

然而,如果问题是“我怎么解析这个?”,而不是“我现有的尝试有什么问题?”,我认为impl的解决方案更有意义(我也同意使用正则表达式进行解析的观点) TeX通常是一个坏主意) - 或者更好的是,像Regexident一样分两步完成。


  

如果使用正则表达式来解析TeX不是一个好主意,那么您建议使用什么方法来解析TeX?

首先,作为一般的经验法则,如果我不能自己编写正则表达式来解决问题,我不想用正则表达式来解决它,因为我很难搞清楚它从现在开始几个月。有时我会将其分解为子表达式,或使用(?x)并使用注释加载它,但通常我会寻找其他方式。

更重要的是,如果你有一个真正的解析器可以使用你的语言并给你一棵树(或任何合适的)你可以走路和搜索 - 例如,对于XML来说etree,那么对于处理该语言时遇到的每个问题,你都有90%的解决方案。一个快速和肮脏的正则表达式(特别是你不能自己编写的正则表达式)只能让你解决下一个问题的10%。而且,如果我今天遇到问题,我将在接下来的几个月里有更多的问题。

那么,Python中的TeX解析器是什么?老实说,我不知道。我知道scipy / matplotlib有一些能做到这一点,所以我可能先看一下。除此之外,请查看Google,PyPI以及tex.stackexchange.com。在搜索中出现的第一件事是TexcallerplasTeX。我不知道它们有多好,或者它们是否适合您的用例,但是不应该花很长时间来浏览教程并找出答案。

如果事实证明那里没有任何东西,并且归结为自己写一些东西,例如pyparsing和正则表达式,那么这是一个更难的选择。有些语言,很容易定义你关心的子集,剩下的就是巨大的未解释的令牌,在这种情况下,真正的解析器就像正则表达式一样容易,所以你也可以这样做。其他语言,你必须处理一半的语法才能做任何有用的事情,所以我甚至都不会尝试。在决定走哪条路之前,我需要花点时间思考一下并尝试两种方式。