Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/315.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 正则表达式如何获取中间字符串_Python_Regex - Fatal编程技术网

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

Python 正则表达式如何获取中间字符串,python,regex,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 更具体地说,我想得到问题编号和子问题编号,以及答案之

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

\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)'

但它似乎不像我预期的那样有效。这个表达式有什么问题?

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       ...')]

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       ...')]
这个:

(?:\\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):

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

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

(?:\\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):

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

\\subproblem\{(.*?)\}\n+(.*?)\n+(?=\\problem|\\subproblem|\\end)
如果问题真的是“这个表达式有什么问题?”,那么答案如下:

  • 您正在尝试将换行符与
    *?
    匹配。你需要
    (?s)
    才能让它工作
  • 在正则表达式中间没有显式的空格和换行,在源文本中没有任何对应的字符。你需要
    (?x)
    才能让它工作
这可能不是这个表达的全部错误。但是只需添加
(?sx)
,将其转换为原始字符串(因为我不相信自己能够正确地混合Python引用和正则表达式引用),然后删除
\n
就可以得到以下结果:

r'(?sx)(\\problem{(.*?)}? \\subproblem{(.*?)} (.*?)) (\\problem|\\subproblem|\\end)'
这将返回2个匹配项而不是0,这可能是对正则表达式进行的最小更改

然而,如果问题是“我如何解析这个?”,而不是“我现有的尝试有什么问题?”,我认为impl的解决方案更有意义(我也同意使用regex解析TeX通常是个坏主意的观点)——或者,更好的是,像Regexident那样分两步进行



如果使用regex解析TeX不是一个好主意,那么您会建议使用什么方法来解析TeX

首先,作为一般的经验法则,如果我不能自己编写正则表达式来解决问题,我不想用正则表达式来解决它,因为几个月后我将很难弄明白它。有时我会将它分解成子表达式,或者使用
(?x)
并用注释加载它,但通常我会寻找另一种方法

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

那么,Python中TeX的好解析器是什么?老实说,我不知道。我知道
scipy
/
matplotlib
有一些功能,所以我可能会先看看。除此之外,请查看谷歌、PyPI,也许还有tex.stackexchange.com。搜索中首先出现的是和。我不知道它们有多好,也不知道它们是否适合您的用例,但浏览教程并找出答案应该不会花太长时间

如果结果是什么都没有,归结到自己写东西,比如vs.regex,那么这是一个更艰难的选择。在某些语言中,很容易只定义您关心的子集,而将其余部分作为巨大的未解释标记,在这种情况下,真正的解析器将与正则表达式一样简单,因此您不妨这样做。在其他语言中,在做任何有用的事情之前,你必须处理一半的语法,所以我甚至不会尝试。在决定走哪条路之前,我必须花一点时间来考虑它,并尝试两种方法。

如果问题真的是“这个表达式有什么问题?”,下面是答案:

  • 您正在尝试将换行符与
    *?
    匹配。你需要
    (?s)
    才能让它工作
  • 在正则表达式中间没有显式的空格和换行,在源文本中没有任何对应的字符。你需要
    (?x)
    才能让它工作
这可能不是这个表达的全部错误。但是只需添加
(?sx)
,将其转换为原始字符串(因为我不相信自己能够正确地混合Python引用和正则表达式引用),然后删除
\n
就可以得到以下结果:

r'(?sx)(\\problem{(.*?)}? \\subproblem{(.*?)} (.*?)) (\\problem|\\subproblem|\\end)'
这将返回2个匹配项而不是0,这可能是对正则表达式进行的最小更改

然而,如果问题是“我如何解析它?”,而不是“我现有的尝试有什么问题?”,我认为impl的解决方案