V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
guiqiqi
V2EX  ›  正则表达式

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

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

    想了一中午,也没想出来这个改怎么写,一个头四个大;各个搜索引擎都查过了,最后只能到 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   ·   实用小工具   ·   3011 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 14:08 · PVG 22:08 · LAX 06:08 · JFK 09:08
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.