正则想到脑子疼,求大家帮帮忙 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
guiqiqi
V2EX    正则表达式

正则想到脑子疼,求大家帮帮忙

  •  
  •   guiqiqi 2018-08-05 14:39:44 +08:00 4182 次点击
    这是一个创建于 2624 天前的主题,其中的信息可能已经有所发展或是发生改变。

    想了一中午,也没想出来这个改怎么写,一个头四个大;各个搜索引擎都查过了,最后只能到 v2 上来求助。

    源字符串是题目的选项:

    A. A 类 - 3.2 B. B 类 - 6.4 C. C 类 - 12.8 D. D 类 - 25.6

    想要将选项和选项的内容分开并获取到,即获取到以下四个分组:

    [('A', 'A 类 - 3.2'), ('B', 'B 类 - 6.4'), ('C', 'C 类 - 12.8'), ('D', 'D 类 - 25.6')]

    上网查有说到用环视,可是我在贪婪匹配下总是得不到想要的结果,以下是我现在能想到的最接近的正则:

    >>> text = "A. A 类 - 3.2 B. B 类 - 6.4 C. C 类 - 12.8 D. D 类 - 25.6" >>> pattern = re.compile(r"(?P<option>\w+)[、\.](?P<content>(?!.*?[A-Z]\.).*)") >>> pattern.findall(text) [('D', ' D 类 - 25.6')] >>> pattern = re.compile(r"(?P<option>\w+)[、\.](?P<content>.*(?!.*?[A-Z]\.))") >>> pattern.findall(text) [('A', ' A 类 - 3.2 B. B 类 - 6.4 C. C 类 - 12.8 D. D 类 - 25.6')] >>> 

    谢谢大家!

    第 1 条附言    2018-08-05 15:16:56 +08:00
    选项内容暂是没有用 [A-Z]\. 开头的,应该可以以这个作为区分,其他的貌似都出现了,感谢!
    17 条回复    2018-08-05 16:51:12 +08:00
    nazor
        1
    nazor  
       2018-08-05 14:52:50 +08:00 via iPhone
    选项内容有格式限制吗?没有格式限制,有歧义啊。
    IvanLi127
        2
    IvanLi127  
       2018-08-05 14:57:11 +08:00 via Android
    目前例子这个还是能用正则搞的 用 A. 这样的东西区分选项。还有不要用贪婪模式
    guiqiqi
        3
    guiqiqi  
    OP
       2018-08-05 15:02:18 +08:00
    @nazor 对啊,选项内容是 `.*` 的,我头都大了。。。
    pandacat
        4
    pandacat  
       2018-08-05 15:02:45 +08:00
    (([ABCD])\. +(\2\W+\d+\.?\d+))
    这样?
    guiqiqi
        5
    guiqiqi  
    OP
       2018-08-05 15:03:17 +08:00
    @IvanLi127 我后面的那个环视 `(?!.*?[A-Z]\.)` 是想用 A.这样的区分,还是不知道怎么搞,求赐教!
    guiqiqi
        6
    guiqiqi  
    OP
       2018-08-05 15:05:56 +08:00
    @pandacat 谢谢您,但是我忘了说了,选项内容是 .* 的。。。头大
    guiqiqi
        7
    guiqiqi  
    OP
       2018-08-05 15:09:54 +08:00
    @nazor @IvanLi127 @pandacat
    看了看数据,现在暂时没有用 大写字母 [A-Z] 加 . 作为开头的。非常感谢~
    imn1
        8
    imn1  
       2018-08-05 15:27:01 +08:00
    In [1]: text = "A. A 类 - 3.2 B. B 类 - 6.4 C. C 类 - 12.8 D. D 类 - 25.6"

    In [2]: import regex as re

    In [3]: re.findall(r'([A-Z])\.\s+(.+?\d\.\d)(?:\s|$)',text)
    Out[3]:
    [('A', 'A 类 - 3.2'),
    ('B', 'B 类 - 6.4'),
    ('C', 'C 类 - 12.8'),
    ('D', 'D 类 - 25.6')]

    关键在于 里面一个 +? ,用对地方就行
    guiqiqi
        9
    guiqiqi  
    OP
       2018-08-05 15:44:43 +08:00
    @imn1 谢谢您的回复,但是我这里这个选项是没有格式限制的,不一定是 `\d\.\d`,当我的数据变成其他格式的时候,+?我这里只匹配到选项后的第一个字符(即没有贪婪匹配):

    ```
    >>> pattern = re.compile(r"(?P<option>\w+)[、\.](?P<content>.+?)")
    >>> pattern.findall("A.C 类 B.D 类 C.E 类 D.F 类")
    [('A', 'C'), ('B', 'D'), ('C', 'E'), ('D', 'F')]
    ```

    我这里中间有的分隔符是用中文顿号分割的,所以写成了 `[、\.]` 的形式。
    co3site
        10
    co3site  
       2018-08-05 15:48:08 +08:00
    首先你把问题描述清楚,看了你一连串的回复,根本不知道你的目标字符串到底是什么样的
    imn1
        11
    imn1  
       2018-08-05 15:54:06 +08:00
    你这样说的话,基本没法做
    我很怀疑每字段不是空格分开,而是<tab>
    如果只是空格,又格式不定的话,设计这个 log 格式的人本身就有问题
    Kilerd
        12
    Kilerd  
       2018-08-05 16:07:21 +08:00
    同 10L,看完下来根本不知道你文本到底是怎样的。表述不清楚。
    guiqiqi
        13
    guiqiqi  
    OP
       2018-08-05 16:21:16 +08:00
    @co3site @Kilerd 不好意思啊,可能表述的不是很清楚,我在这里在多举几个例子可能会好一些:

    Example 1: A. 13 B. 12 C. 11 D. 10
    Example 2: A. 选项 1 B. 选项 2 C. 选项 3 D. 选项 4
    Example 3: A. A 类 - 3.2 B. B 类 - 6.4 C. C 类 - 12.8 D. D 类 - 25.6
    Example 4: A. C 类 B. D 类 C. E 类 D. F 类

    归纳下来数据格式就是:
    A. 数据 B. 数据 ....
    而其中的数据不包含大写字母和 . 的连续组合。希望这里表述的足够清楚。

    @imn1 不是 log 哈,老妈最近要有一个考试,她基本不怎么会上网,从网上给她找了些题目,但是格式很不统一,我想用正则提出来入库给她做一个小程序让她练(能实现那种答案做完之后跳出来还有解析的那种,现在就剩答案格式不好提取了),非常感谢回复。
    nazor
        14
    nazor  
       2018-08-05 16:21:34 +08:00 via iPhone
    @guiqiqi 分析特殊字符吧,只靠文字有歧义,正则也没用。
    guiqiqi
        15
    guiqiqi  
    OP
       2018-08-05 16:25:41 +08:00
    @nazor 谢谢!不知道这个分析特殊字符是什么意思,可能是打错了我觉得~,如果是分割特殊字符的话,我实在找不出来固定的特殊字符,因为选项字符串中也含有空格 头大
    imn1
        16
    imn1  
       2018-08-05 16:33:50 +08:00   2
    In [14]: re.findall(r'(?:\.\s+)(.+?)(?:\s[A-D]|$)',text)
    Out[14]: ['A 类 - 3.2', 'B 类 - 6.4', 'C 类 - 12.8', 'D 类 - 25.6']

    放弃直接提取 ABCD,反正按顺序自己添加就行
    keyword 是每项开头有「 ABCD.空格」,如果不符合全部我也没办法了
    guiqiqi
        17
    guiqiqi  
    OP
       2018-08-05 16:51:12 +08:00
    @imn1 感谢,问题已解决!
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     5549 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 27ms UTC 08:56 PVG 16:56 LAX 01:56 JFK 04:56
    Do have faith in what you're doing.
    ubao snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86