Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sql-server-2005/2.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 regexp与组中的一个或多个字符相匹配,但特定的备选字符除外_Python_Regex_Python 2.7 - Fatal编程技术网

python regexp与组中的一个或多个字符相匹配,但特定的备选字符除外

python regexp与组中的一个或多个字符相匹配,但特定的备选字符除外,python,regex,python-2.7,Python,Regex,Python 2.7,我想匹配=/*+-的所有组合,除了=和=>之外。我该怎么做 r = re.compile(r'[<>=/*+-]+') r=re.compile(r'[=/*+-]+') 这与集合中的一个或多个字符匹配,但我不知道如何防止它与=或=>模式匹配。我猜这和消极的向前看或向后看有关,但我很难理解这一点 澄清:我确实想匹配=/*+-中的所有字符组合,除了=和=>之外。换句话说,我想找到仅由这些字符组成的最大长度连续子字符串——如果子字符串等于=或=>,则不应将其视为匹配 我很抱歉没有

我想匹配
=/*+-
的所有组合,除了
=
=>
之外。我该怎么做

 r = re.compile(r'[<>=/*+-]+')
r=re.compile(r'[=/*+-]+')
这与集合中的一个或多个字符匹配,但我不知道如何防止它与
=
=>
模式匹配。我猜这和消极的向前看或向后看有关,但我很难理解这一点


澄清:我确实想匹配
=/*+-
中的所有字符组合,除了
=
=>
之外。换句话说,我想找到仅由这些字符组成的最大长度连续子字符串——如果子字符串等于
=
=>
,则不应将其视为匹配

我很抱歉没有早些澄清,但这似乎是一个足够简单的问题陈述,不需要额外的澄清

示例案例:

  • pow-pow->bah-bah
    包含匹配项
    ->
  • a++->*b//c
    包含匹配的
    ++->*
    /
  • =>3这可能有效:

    pat = re.compile(r'((?!=|=>)[<>=/*+-]+)')
    
    pat=re.compile(r'(((?!=|=>)[=/*+-]+))
    
    它使用负面环视语法,详细描述如下:

    编辑:不幸的是,当喂食“=>”时,上面的简单环视将与“>”匹配,因此,为了解决这一问题,它可能会变得有点毛茸茸的:

    pat = re.compile(r'((?!=>|(?!=)>)([<>/*+-]|[<>=/*+-]{2,10}))')
    
    pat=re.compile(r'((?!=>)(?!=)>)([/*+-].[=*+-]{2,10})))
    
    我假设您不希望匹配长度超过10的字符串。这将匹配分为单字符运算符(我们从中排除“=”)和多字符运算符(其中“=”可以),除了“=>”--它还排除了我们不感兴趣的边缘情况,仅排除了被拒绝“=>”的“>”


    然而,这是完全不可读的,如果它进入了您的代码中,应该会有大量的注释。同意其他评论者的观点,即单一正则表达式不适合此问题

    编辑:实施了abarnert的以下建议:

    我将把它分为两部分:

    第一部分将返回所有匹配项的列表-包括您不希望匹配的“=>”和“=”

    p1 = re.compile(r'[<>=/*+-]+')
    

    为了澄清,
    =
    不应该匹配?此外,这看起来像是在匹配操作符,如
    +
    +=
    ,但像
    /*>=
    这样的写入字符串将匹配。这就是你想要的吗?如果你坚持要改变路线,我认为最好把它分成两个表达式——一个匹配你想要的字符,然后一个过滤掉你不想要的字符。可能只有一个表达式可以完成这一切,但它可能非常不可读。@nfazzio:而且它的效率也可能非常低(甚至可能需要指数回溯,而串联的两个线性正则表达式显然仍然是线性的,它们也非常简单和快速)。@nfazzio:IIRC,有人证明了这一点(使用Perl regexp,这与Python不太一样,但非常接近)不可能确定哪些正则表达式在次指数时间内可以是指数的。你可以很容易地编写一个工具来标记任何可能是指数的正则表达式,但这会给你带来大量的误报。有关简单的讨论和许多好的链接,请参阅。@JasonS:因为这里有很多不明显的边缘情况,请参阅与其在评论中一一回答,让我们去猜测结果,不如提供一个测试用例和预期输出的列表,让这一点变得明确。这个问题对那些没有读过几十条零散评论的人来说应该是有意义的,而这一条并不是。只是说说而已“可能行得通”,尤其是没有任何解释,并不能真正起到回答的作用。@TomMcClure:我将
    re
    更改为
    pat
    ,以避免对
    re
    模块造成阴影。此外,这也不起作用
    打印搜索(pat,,).group()
    匹配
    '
    。根据OP,他很好,但这对任何情况都是错误的,这是一个有效的匹配,但从
    =
    =>
    开始-例如,
    =>
    将匹配
    而不是
    =>
    。很好的方法,很好的简单实现。但是两个小问题。First、 如果您有一个已编译的regexp,请使用
    p1.findall(s)
    ,而不是
    re.findall(p1,s)
    。其次,使用
    finditer
    而不是
    findall
    ;没有理由仅仅为了迭代而构建一个列表。@abarnert:谢谢你的建议-我已经实现了它们。关于
    可调用迭代器的问题类型:如果我在列表理解中迭代一次,我如何再次迭代它?如果我执行了列表理解两次,第一次生成我想要的内容,但第二次生成空列表。迭代器不能迭代两次。创建
    匹配项后,
    所有匹配项都是空的。如果确实需要迭代两次,则可能需要列表。但在大多数情况下,您不需要有任何需要,所以不必支付费用。请参阅本教程中的和以下部分。
    
    all_matches = p1.finditer(your_string)
    matches = [match.group() for match in all_matches if match.group() not in ('=', '=>')]