正则表达式 python 不加倍组模式

Regex python non doubling the group pattern

谁能看看这个正则表达式?

PATTERN=r"([A-Z]{3}[\/I\\s\-\|]?[A-Z]{3})\s*(BUY|SELL)+\s*(-\d+\.\d+|\d+\.\d+\+|\d+\.\d+)?\s*((SL|TP)?\s*(-\d+\.\d+|\d+\.\d+\+|\d+\.\d+)?\s*(?:(\(?))((-\d+|\d+\+|\d+)?\s*Pips)?(?:\))?)?\s*((SL|TP)?\s*(-\d+\.\d+|\d+\.\d+\+|\d+\.\d+)?\s*(?:(\(?))((-\d+|\d+\+|\d+)?\s*Pips)?(?:\))?)?\s*(Intra-Day Trade|SWING TRADE)?\s*"gm

有什么方法可以匹配多个组作为 SL 或 TP 而不必重写整个

((SL|TP)?\s*(-\d+\.\d+|\d+\.\d+\+|\d+\.\d+)?\s*(?:(\(?))((-\d+|\d+\+|\d+)?\s*Pips)?(?:\))?)?

组的模式?

我正在尝试获取 SL 和 TP 组(在本例中): 示例:

import re
PATTERN=r"([A-Z]{3}[\/I\\s\-\|]?[A-Z]{3})\s*(BUY|SELL)+\s*(-\d+\.\d+|\d+\.\d+\+|\d+\.\d+)?\s*((SL|TP)?\s*(-\d+\.\d+|\d+\.\d+\+|\d+\.\d+)?\s*(?:(\(?))((-\d+|\d+\+|\d+)?\s*Pips)?(?:\))?)?\s*((SL|TP)?\s*(-\d+\.\d+|\d+\.\d+\+|\d+\.\d+)?\s*(?:(\(?))((-\d+|\d+\+|\d+)?\s*Pips)?(?:\))?)?\s*(Intra-Day Trade|SWING TRADE)?\s*"
text="""EURCAD SELL 1.36599 SL 1.37701 (110 Pips) TP 1.34017 (258 Pips) Intra-Day Trade """
match = re.match(PATTERN, text)
groups = list(match.groups())
for idx, x in enumerate(groups):
  print(f"Group number {idx}, content: {x}")

输出:

Group number 0, content: EURCAD
Group number 1, content: SELL
Group number 2, content: 1.36599
Group number 3, content: SL 1.37701 (110 Pips)
Group number 4, content: SL
Group number 5, content: 1.37701
Group number 6, content: (
Group number 7, content: 110 Pips
Group number 8, content: 110
Group number 9, content: TP 1.34017 (258 Pips)
Group number 10, content: TP
Group number 11, content: 1.34017
Group number 12, content: (
Group number 13, content: 258 Pips
Group number 14, content: 258
Group number 15, content: Intra-Day Trade

组的非重复代码:

import re
PATTERN=r"([A-Z]{3}[\/I\\s\-\|]?[A-Z]{3})\s*(BUY|SELL)+\s*(-\d+\.\d+|\d+\.\d+\+|\d+\.\d+)?\s*((SL|TP)?\s*(-\d+\.\d+|\d+\.\d+\+|\d+\.\d+)?\s*(?:(\(?))((-\d+|\d+\+|\d+)?\s*Pips)?(?:\))?)+\s*\s*(Intra-Day Trade|SWING TRADE)?\s*"
text="""EURCAD SELL 1.36599 SL 1.37701 (110 Pips) TP 1.34017 (258 Pips) Intra-Day Trade """
match = re.match(PATTERN, text)
groups = list(match.groups())
for idx, x in enumerate(groups):
  print(f"Group number {idx}, content: {x}")

输出不重复码:

Group number 0, content: EURCAD
Group number 1, content: SELL
Group number 2, content: 1.36599
Group number 3, content: 
Group number 4, content: TP
Group number 5, content: 1.34017
Group number 6, content: 
Group number 7, content: 258 Pips
Group number 8, content: 258
Group number 9, content: Intra-Day Trade

但如果不将它们分配给两个不同的组,我就做不到。 非不同组的示例 regex101 link。 这显然给了我:

我要匹配:

EURCAD SELL 1.36599
SL 1.37701 (110 Pips)
TP 1.34017 (258 Pips)
Intra-Day Trade

还有 (-):

EURCAD SELL 1.36599
SL 1.37701 (110 Pips)
Intra-Day Trade

(-)

EURCAD SELL 1.36599
TP 1.34017 (258 Pips)
Intra-Day Trade

(-)

EURCAD SELL 1.36599

(-)

EURCAD SELL 1.36599
SL 1.37701 (110 Pips)
TP 1.34017 (258 Pips)

(-)

EURCAD SELL 1.36599
SL 1.37701 (110 Pips)
TP 1.34017 (258 Pips)

SWING TRADE

(-)

EUR/CAD BUY 1.36599
SWING TRADE

(-)

EUR|CAD BUY 1.36599
SWING TRADE

(-)

EUR\CAD BUY 1.36599
SWING TRADE

(-)

EUR|CAD BUY 1.36599
SWING TRADE

(-)

EURICAD BUY 1.36599
Intra-Day Trade

基本上这些都是人工输入的字符串,我可能必须提供所有可能导致正确“交易”信号的匹配项。

显然,通过阅读正则表达式,您可以获得我要匹配的内容,但我并不是真的在寻求正则表达式模式的帮助,而只是寻求 GROUPS 语法的帮助(这并没有导致正确的匹配无需重复代码)。

这是模式regex101 link,大家自行测试。 提前谢谢你。

如果您重复捕获组,则捕获组具有上次迭代的值。

您试过的模式,可以缩短为:

([A-Z]{3}[\/I\\s|-]?[A-Z]{3})\s*(BUY|SELL)+\s*(-?\d+\.\d+|\d+\.\d+\+)?(?:\n(SL|TP)\s*(-?\d+\.\d+|\d+\.\d+\+)\s*(\((-?\d+|\d+\+)?\s*Pips\)))*\s*(Intra-Day Trade|SWING TRADE)?

关于缩短模式的一些注意事项:

  • 这部分(?:(\(?))可以写成\(?
  • 这部分(-\d+\.\d+|\d+\.\d+\+|\d+\.\d+)可以写成(-?\d+\.\d+|\d+\.\d+\+)
  • Pips 部分的括号如 (110 Pips) 不是可选的
  • 对于非重复模式,您使用所有可选部分重复了非捕获组 1 次或多次。相反,您可以选择使用固定格式重复非捕获组,以便所有内部部分都不是可选的

如果要重复捕获组并具有这些值,并且可以使用 PyPi regex module,则可以使用 capturesdict() 并使用命名捕获组

具有命名捕获组的模式:

(?P<word1>[A-Z]{3}[\/I\\s|-]?[A-Z]{3})\s*(?P<word2>BUY|SELL)+\s*(?P<word3>-?\d+\.\d+|\d+\.\d+\+)?(?:\n(?P<word4>SL|TP)\s*(?P<word5>-?\d+\.\d+|\d+\.\d+\+)\s*(?P<word6>\((-?\d+|\d+\+)?\s*Pips\)))*\s*(?P<wor7>Intra-Day Trade|SWING TRADE)?

Regex demo | Python demo

例如

import regex

pattern = r"(?P<word1>[A-Z]{3}[\/I\\s|-]?[A-Z]{3})\s*(?P<word2>BUY|SELL)+\s*(?P<word3>-?\d+\.\d+|\d+\.\d+\+)?(?:\n(?P<word4>SL|TP)\s*(?P<word5>-?\d+\.\d+|\d+\.\d+\+)\s*(?P<word6>\((-?\d+|\d+\+)?\s*Pips\)))*\s*(?P<wor7>Intra-Day Trade|SWING TRADE)?"

s = ("EURCAD SELL 1.36599\n"
            "SL 1.37701 (110 Pips)\n"
            "TP 1.34017 (258 Pips)\n\n"
            "Intra-Day Trade\n\n"
            "EUR/CAD BUY 1.36599\n"
            "SWING TRADE")

matches = regex.finditer(pattern, s, regex.M)

for matchNum, match in enumerate(matches, start=1):
    print(match.capturesdict())

输出

{'word1': ['EURCAD'], 'word2': ['SELL'], 'word3': ['1.36599'], 'word4': ['SL', 'TP'], 'word5': ['1.37701', '1.34017'], 'word6': ['(110 Pips)', '(258 Pips)'], 'wor7': ['Intra-Day Trade']}
{'word1': ['EUR/CAD'], 'word2': ['BUY'], 'word3': ['1.36599'], 'word4': [], 'word5': [], 'word6': [], 'wor7': ['SWING TRADE']}