鱼C论坛

 找回密码
 立即注册
查看: 2706|回复: 15

[已解决]数据结尾不规整,正则该咋办?(正则语法的边界断言)

[复制链接]
发表于 2022-8-31 10:40:18 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本帖最后由 blackantt 于 2022-9-1 11:47 编辑

数据大致有如下4种情况,想把最多2种词性的第一部分取出来



------------------------------------------------------------------------ 2行词性,都取2行第1个;以前的部分,
<div class="trans-container">

   <ul>
     <li>n. 狗,犬;公狗,公狐,公狼;质量极差的东西;无吸引力的女子;卑鄙小人,无赖;&lt;美,非正式&gt;朋友</li>
     <li>v. 困扰,纠缠;跟踪,尾随</li>
    </ul>
    </div>
    </div>
------------------------------------------------------------------------------------2行词性,想取2行第一个;号以前的部分,可是第2行偏偏没有;号
<div class="trans-container">

   <ul>
     <li>n. 狗,犬;公狗,公狐,公狼;质量极差的东西;无吸引力的女子;卑鄙小人,无赖;&lt;美,非正式&gt;朋友</li>
     <li>v. 困扰,纠缠</li>
    </ul>
    </div>
    </div>

------------------------------------------------------------------------------------这个只有1行词性,就只取第1个分号之前的

<div class="trans-container">

   <ul>
     <li>n. 狗,犬;公狗,公狐,公狼;质量极差的东西;无吸引力的女子;卑鄙小人,无赖;&lt;美,非正式&gt;朋友</li>
    </ul>
    </div>
    </div>


---------------------------------------------------------------------------------这个只有1行词性,就只取第1个分号之前的(实际上数据里根本就没有;号)
<div class="trans-container">

   <ul>
     <li>n. 狗,犬</li>
    </ul>
    </div>
    </div>
最佳答案
2022-9-1 10:12:05
regex_1 = re.compile(r'(?<=trans-container).*?(?=\/ul)', re.DOTALL)

regex_2 = re.compile(r'(?<=<li>).+?(?=(?=[;;])|(?=<\/li>))')
我来解释下
第一个正则用来缩小范围,把匹配范围控制在trans-container到第一个</ul>之间;
第二个正则真正用来匹配你要的带词性的释义,这个正则分成了三个部分:
1. 如果前面是<li>
2. 真正要匹配的内容
3. 如果后面是中文分号或者英文分号,又或者是</li>
为了让你可以直接使用匹配到的内容我就这么写了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2022-8-31 11:32:46 | 显示全部楼层
re.compile(r'trans-container">.+?;', re.DOTALL)
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-8-31 15:03:54 | 显示全部楼层
学习一下
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-8-31 20:48:38 | 显示全部楼层
ss='''
<div class="trans-container">

   <ul>
     <li>n. 狗,犬;公狗,公狐,公狼;质量极差的东西;无吸引力的女子;卑鄙小人,无赖;<美,非正式>朋友</li>
     <li>v. 困扰,纠缠;跟踪,尾随</li>
    </ul>
    </div>
    </div>
'''
print(re.findall('trans-container">\s+.\S+\s+.+?;',ss))
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2022-9-1 09:35:26 | 显示全部楼层

sorry,昨天帖子还没写完,不知咋的它就把半截内容发出来了。 今天才看到。现在原数据有4种情况,这种该怎么弄呢?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2022-9-1 09:39:10 | 显示全部楼层

sorry,昨天帖子还没写完,不知咋的它就把半截内容发出来了。 今天才看到。现在原数据有4种情况,这种该怎么弄呢?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-9-1 09:58:31 | 显示全部楼层
blackantt 发表于 2022-9-1 09:39
sorry,昨天帖子还没写完,不知咋的它就把半截内容发出来了。 今天才看到。现在原数据有4种情况,这种该 ...


针对你说的四种情况,我自己用正则试了试,用两个正则表达式可以完成任务,不知道你接不接受
第一个正则用来确定tran-container范围,第二个正字用于提取你要的内容
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2022-9-1 10:01:49 | 显示全部楼层
Brick_Porter 发表于 2022-9-1 09:58
针对你说的四种情况,我自己用正则试了试,用两个正则表达式可以完成任务,不知道你接不接受

好啊,请贴出来。
那最后是用if。。else来条件匹配覆盖这4种情况吗?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-9-1 10:05:10 | 显示全部楼层
blackantt 发表于 2022-9-1 10:01
好啊,请贴出来。
那最后是用if。。else来条件匹配覆盖这4种情况吗?

稍等,确实用到了类似if ... else这样的结构,不过是正则表达式版本的
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-9-1 10:12:05 | 显示全部楼层    本楼为最佳答案   
regex_1 = re.compile(r'(?<=trans-container).*?(?=\/ul)', re.DOTALL)

regex_2 = re.compile(r'(?<=<li>).+?(?=(?=[;;])|(?=<\/li>))')
我来解释下
第一个正则用来缩小范围,把匹配范围控制在trans-container到第一个</ul>之间;
第二个正则真正用来匹配你要的带词性的释义,这个正则分成了三个部分:
1. 如果前面是<li>
2. 真正要匹配的内容
3. 如果后面是中文分号或者英文分号,又或者是</li>
为了让你可以直接使用匹配到的内容我就这么写了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-9-1 10:17:08 | 显示全部楼层
(?<=<li>)这个语句其实是个条件语句,意思是如果前面是<li>。请注意,这个语句只会匹配位置

.+?就是我们真正要匹配的内容

(?=(?=[;;])|(?=<\/li>))这条语句也是一个条件语句,内部它又把两个条件句用|(或者的意思)合并了,说人话就是如果后面是中英文分号或者</li>。请注意,这条语句同样不匹配字符,只匹配位置
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2022-9-1 10:29:12 | 显示全部楼层
Brick_Porter 发表于 2022-9-1 10:12
我来解释下
第一个正则用来缩小范围,把匹配范围控制在trans-container到第一个之间;
第二个正则真正用 ...

感谢,我学习下
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2022-9-1 10:38:57 | 显示全部楼层

谢谢,这么详细的解释
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2022-9-1 11:00:14 | 显示全部楼层
本帖最后由 blackantt 于 2022-9-1 11:09 编辑


再次感谢,第一次见到。我一直在用{}拼来拼去,总是不对。现在好了。



import re

ss='''
<div class="trans-container">

   <ul>
     <li>n. 狗,犬;公狗,公狐,公狼;质量极差的东西;无吸引力的女子;卑鄙小人,无赖;&lt;美,非正式&gt;朋友</li>
     <li>v. 困扰,纠缠</li>
    </ul>
    </div>
    </div>
'''
regex_1 = re.compile(r'(?<=trans-container).*?(?=\/ul)', re.DOTALL)
regex_2 = re.compile(r'(?<=<li>).+?(?=(?=[;])|(?=<\/li>))')
ab = re.findall(regex_2, ss)

if re.findall(regex_1,ss) and re.findall(regex_2,ss):
    #print(re.findall(regex_2, ss))
    print(ab[0],'\n',ab[1],sep='')
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-9-1 11:23:42 | 显示全部楼层
blackantt 发表于 2022-9-1 11:00
再次感谢,第一次见到。我一直在用{}拼来拼去,总是不对。现在好了。

我是用的这个正则语法叫做边界断言,不是很好理解,我自己也是找了很多教程对照看才理解的。如果你想进一步了解可以联系我
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2022-9-1 11:46:44 | 显示全部楼层
Brick_Porter 发表于 2022-9-1 11:23
我是用的这个正则语法叫做边界断言,不是很好理解,我自己也是找了很多教程对照看才理解的。如果你想进一 ...

好的
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-9-28 16:17

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表