【问题标题】:Split an expression into list based on some silly conditions根据一些愚蠢的条件将表达式拆分为列表
【发布时间】:2018-08-16 22:00:00
【问题描述】:

我有一个如下的表达式:

^f04[^z]*$ ^f00bar$,^.*f04.*&~(.*z.*)$ AND foo bar OR f04ba

所以,我想在这里做的是:

如果 2 个连续的单词或正则表达式形式的单词由空格分隔,则将该空格更改为单词 AND,如果它们由 ,(逗号)分隔,则将其更改为单词 OR,如果它们由 AND 和 OR 分隔让它们保持原样。

所以,现在应该是这样的:

^f04[^z]*$ AND ^f00bar$ OR ^.*f04.*&~(.*z.*)$ AND foo AND bar OR f04ba

另外,最后如果这两个词用 AND 分隔,那么我想在它周围加上一个括号,所以它看起来像下面这样:

(^f04[^z]*$ AND ^f00bar$) OR (^.*f04.*&~(.*z.*)$ AND foo AND bar) OR f04ba

另一个例子:

1.) foo bar OR cat AND crap,flu -> (foo AND bar) OR (cat AND CRAP) OR flu

2.) ^.*f04.*&~(.*z.*)$ /k1=v1/ /k2=v2/ bar, cat ->

(^.*f04.*&~(.*z.*)$ AND /k1=v1/ AND /k2=v2/ AND bar) OR cat

最好的方法是什么?

我想像下面那样做:

  1. 将表达式按空格拆分为列表。 列表将如下所示:

    [^f04[^z]*$,^f00bar$,',',^.*f04.*&~(.*z.*)$,AND,foo,bar,OR,f04ba]
    
  2. 遍历列表,如果每个替代词看起来都不像 AND、OR 或 ',则在该单词后添加 AND,如果是 ',',则将其更改为 OR。

这样好吗?在 Python 中执行此操作的最佳方法应该是什么?

【问题讨论】:

  • 只是一个细节,但应该是... OR (... AND ...) OR ...还是... OR \(... AND ...\) OR ...
  • 是否有 , 不应该被替换但被解释为正则表达式的一部分,如 {2,4}[^,.-]
  • 添加示例请检查
  • 是的,正则表达式的逗号部分应被视为单词的一部分。
  • 我在 perl 中使用以下代码执行此操作:将列表拆分为单词,其中一些单词包含逗号作为正则表达式的一部分-> my @array; ## 用逗号分割输入表达式并存储在一个数组中 while ( $exp =~ m{ ((?: [^(),]+ | ( ( (?: [^()]+ | (?2) )* ) ) )+) (?: ,\s* | $) }xg ) { push @array, $1;

标签: python regex python-2.7 list


【解决方案1】:

您可以使用... 正则表达式来操作您的正则表达式。首先,使用re.split在每个,OR和每个空格分别在AND进行分割。

>>> r = "^f04[^z]*$ ^f00bar$,^.*f04.*&~(.*z.*)$ AND foo bar OR f04ba"
>>> groups = [[y for y in re.split(" |AND", x) if y] for x in re.split(",|OR", r)]
>>> groups
[['^f04[^z]*$', '^f00bar$'], ['^.*f04.*&~(.*z.*)$', 'foo', 'bar'], ['f04ba']]

然后,只需将str.join 重新组合在一起并将AND 组包装到(...) 中:

>>> ' OR '.join('(' + ' AND '.join(grp) + ')' for grp in groups)
'(^f04[^z]*$ AND ^f00bar$) OR (^.*f04.*&~(.*z.*)$ AND foo AND bar) OR (f04ba)'

但是,请注意,这将在 all , 处拆分,即使这些应该是正则表达式的一部分。我真的不明白应该如何区分这些。 (这可能使用更复杂的正则表达式而不是 ,|OR 就像您在 cmets 中显示的那样,我没有尝试过。)

此外,这会将连词的每个部分包装成(...),即使它们只有一个元素。这可以通过更复杂的列表理解来解决,首先检查组的len(没有空元素)。

>>> ' OR '.join('(' + ' AND '.join(grp) + ')' if len(grp) > 1 and len(groups) > 1 
...             else ' AND '.join(grp) for grp in groups)
'(^f04[^z]*$ AND ^f00bar$) OR (^.*f04.*&~(.*z.*)$ AND foo AND bar) OR f04ba'

【讨论】:

  • 逗号不一定是表达式的一部分 -> 表达式可以很简单 -> foo bar cat -> (foo AND bar AND cat)
  • @zubug55 没有逗号就没有问题。
  • 但它根本不应该拆分作为正则表达式一部分的逗号应该只是正则表达式的一部分
  • 用逗号分割的方式是 -> stackoverflow.com/a/9436422/9302655 它在 perl 中;你知道我如何在 python 中做到这一点
  • 在任何像上面这样的正则表达式字符串中,逗号只能以 {3,6} 形式出现吗?
猜你喜欢
  • 2010-10-31
  • 2021-07-24
  • 2012-07-28
  • 1970-01-01
  • 1970-01-01
  • 2017-12-13
  • 1970-01-01
  • 1970-01-01
  • 2021-05-21
相关资源
最近更新 更多