正则表达式两组匹配一切直到模式

时间:2018-05-07 23:23:03

标签: python regex string split

我有以下例子:

Tortillas Bolsa 2a 1kg 4118
Tortillinas 50p 1 31Kg TAB TR 46113
Bollos BK 4in 36p 1635g SL 131
Super Pan Bco Ajonjoli 680g SP WON 100  
Pan Blanco Bimbo Rendidor 567g BIM 49973
Gansito ME 5p 250g MTA MLA 49860

我希望在数字之前保留所有内容,但我也不想要两个大写字母示例:ME, BK。我正在使用^((\D*).*?) [^A-Z]{2,3}

预期结果应为

Tortillas Bolsa
Tortillinas
Bollos
Super Pan Bco Ajonjoli
Pan Blanco Bimbo Rendidor
Gansito

使用正则表达式,我使用我仍然会得到两个大写字母Bollos BKGansito ME

5 个答案:

答案 0 :(得分:2)

使用前瞻预编译正则表达式模式(如下所述)并在列表解析中使用regex.match

>>> import re
>>> p = re.compile(r'\D+?(?=\s*([A-Z]{2})?\s*\d)')
>>> [p.match(x).group() for x in data]

[
 'Tortillas Bolsa',
 'Tortillinas',
 'Bollos',
 'Super Pan Bco Ajonjoli',
 'Pan Blanco Bimbo Rendidor',
 'Gansito'
]

此处,data是您的字符串列表。

详情

\D+?            # anything that isn't a digit (non-greedy)
(?=             # regex-lookahead
\s*             # zero or more wsp chars
([A-Z]{2})?     # two optional uppercase letters
\s*   
\d              # digit
)

如果任何字符串不包含您正在寻找的模式,则列表推导将出错(带有AttributeError),因为re.match在该实例中返回None。然后,您可以在提取匹配部分之前使用循环并测试re.match的值。

matches = []
for x in data:
    m = p.match(x)
    if m:
        matches.append(m.group())

或者,如果您希望占位符None没有匹配项:

matches = []
for x in data:
    matches.append(m.group() if m else None)

答案 1 :(得分:1)

您可以使用前瞻功能:

I_WANT        = '(.+?)' # This is what you want
I_DO_NOT_WANT = '\s(?:[0-9]|(?:[A-Z]{2,3}\s))' # Stop-patterns
RE = '{}(?={})'.format(I_WANT, I_DO_NOT_WANT) # Combine the parts

[re.findall(RE, x)[0] for x in test_strings]
#['Tortillas Bolsa', 'Tortillinas', 'Bollos', 'Super Pan Bco Ajonjoli',
# 'Pan Blanco Bimbo Rendidor', 'Gansito']

答案 2 :(得分:1)

假设:

  • 您要在捕获组中匹配的所有字词都以大写字母开头
  • 每个单词的其余部分仅包含小写字母
  • 单词由单个空格分隔

...您可以使用以下正则表达式:

  1. 使用Unicode character properties

    ^((\p{Lu}\p{Ll}+ )+)
    

    > Try this regex on regex101.

  2. 没有Unicode支持:

    ^(([A-z][a-z]+ )+)
    

    > Try this regex on regex101.

答案 3 :(得分:1)

我建议拆分前两个大写字母或数字并抓住第一个项目:

r = re.compile(r'\b[A-Z]{2}\b|\d')
[r.split(item)[0].strip() for item in my_list]
# => ['Tortillas Bolsa', 'Tortillinas', 'Bollos', 'Super Pan Bco Ajonjoli', 'Pan Blanco Bimbo Rendidor', 'Gansito']

请参阅Python demo

模式详情

  • \b[A-Z]{2}\b - 一个整体(因为\b是字边界)两个大写的ASCII字母词
  • | - 或
  • \d - 数字。

使用.strip(),所有尾随和前导空格都将被修剪。

re.sub的轻微变化:

re.sub(r'\s*(?:\b[A-Z]{2}\b|\d).*', '', s)

请参阅regex demo

<强>详情

  • \s* - 0+空白字符
  • (?:\b[A-Z]{2}\b|\d) - 两个大写字母或数字
  • .* - 其余部分。

答案 4 :(得分:1)

我的2美分

/dts-v1/;
/plugin/;
/ {
compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709";

fragment@0 {
    // Configure the gpio pin controller
    target = <&gpio>;
    __overlay__ {
        pin_state: key_pins@0 {
            brcm,pins = <17>;       // gpio number
            brcm,function = <0>;    // 0 = input, 1 = output
            brcm,pull = <2>;        // 0 = none, 1 = pull down, 2 = pull up
        };
    };
};      

fragment@1 {    
    target-path = "/";
    __overlay__ {
        keypad: proximity@0 {
            compatible = "gpio-keys";
            #address-cells = <1>;
            #size-cells = <0>;

            key: proximity {
                label = "proximity detection";
                linux,code = <61>;          // F3 Key
                gpios = <&gpio 17 1>;       // GPIO 17
                wakeup-source;
            };
        };
    };
};
};

https://regex101.com/r/7xD7DS/1/