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

2018-08-05 14:39:44 +08:00
 guiqiqi

想了一中午,也没想出来这个改怎么写,一个头四个大;各个搜索引擎都查过了,最后只能到 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')]
>>>

谢谢大家!

3938 次点击
所在节点    正则表达式
17 条回复
nazor
2018-08-05 14:52:50 +08:00
选项内容有格式限制吗?没有格式限制,有歧义啊。
IvanLi127
2018-08-05 14:57:11 +08:00
目前例子这个还是能用正则搞的 用 A. 这样的东西区分选项。还有不要用贪婪模式
guiqiqi
2018-08-05 15:02:18 +08:00
@nazor 对啊,选项内容是 `.*` 的,我头都大了。。。
pandacat
2018-08-05 15:02:45 +08:00
(([ABCD])\. +(\2\W+\d+\.?\d+))
这样?
guiqiqi
2018-08-05 15:03:17 +08:00
@IvanLi127 我后面的那个环视 `(?!.*?[A-Z]\.)` 是想用 A.这样的区分,还是不知道怎么搞,求赐教!
guiqiqi
2018-08-05 15:05:56 +08:00
@pandacat 谢谢您,但是我忘了说了,选项内容是 .* 的。。。头大
guiqiqi
2018-08-05 15:09:54 +08:00
@nazor @IvanLi127 @pandacat
看了看数据,现在暂时没有用 大写字母 [A-Z] 加 . 作为开头的。非常感谢~
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
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
2018-08-05 15:48:08 +08:00
首先你把问题描述清楚,看了你一连串的回复,根本不知道你的目标字符串到底是什么样的
imn1
2018-08-05 15:54:06 +08:00
你这样说的话,基本没法做
我很怀疑每字段不是空格分开,而是<tab>
如果只是空格,又格式不定的话,设计这个 log 格式的人本身就有问题
Kilerd
2018-08-05 16:07:21 +08:00
同 10L,看完下来根本不知道你文本到底是怎样的。表述不清楚。
guiqiqi
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
2018-08-05 16:21:34 +08:00
@guiqiqi 分析特殊字符吧,只靠文字有歧义,正则也没用。
guiqiqi
2018-08-05 16:25:41 +08:00
@nazor 谢谢!不知道这个分析特殊字符是什么意思,可能是打错了我觉得~,如果是分割特殊字符的话,我实在找不出来固定的特殊字符,因为选项字符串中也含有空格···· 头大
imn1
2018-08-05 16:33:50 +08:00
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
2018-08-05 16:51:12 +08:00
@imn1 感谢,问题已解决!

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/477019

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX