正则提取文本操作集(python和js)

命理的条文在古书里面都是pdf,要自己一个个手敲,还好有了网络很多工作有人已经做了。但是直接复制下来没有什么作用,因为一条断语往往包含了多条规则,有的还包含了几个方面的断言,这个时候就使用到爬虫+正则表达式来处理了。这里用到了一个在线验证正则的网站https://regex101.com/
1 提取中间字段
下面代码中(?<=(:))是匹配开头的字符串,而(?=(生人))则匹配以生人为结尾的字符串,参考正则 ?<= 和 ?= 用法

def parse_content(content):
    month = re.search(r'(?<=(:)).*(?=(生人))',content).group()
    print(month)
if __name__ == '__main__':
    # parse_txt('file1.txt')
    parse_content('生月论命:正月生人')
# 输出结果为:正月

2 中间存在回车的文本
看到下面的\n是没有问题的,但是如果是回车键,却又问题
1
2
因为.是匹配除换行符(\n、\r)之外的任何单个字符,相等于 [^\n\r]。,而[\s\S]是匹配所有。\s 是匹配所有空白符,包括换行,\S 非空白符,不包括换行。故这里少做一些调整就可以了。

month = re.search(r'(?<=(二、生月对时论六亲))[\s\S]*(?=(三、月上十神论))',content).group()

另外一种解决方案是re.S,这样就支持换行符的匹配了

content = re.search(r'(?<=(二、生月对时论六亲)).*(?=(三、月上十神论))',content,re.S).group()

3 正则提取字符串
内容如下,按照行进行解析,分为四段

正月:子时。兄弟排行、四。五岁体弱、父母双全。(大运忌午)
正月:丑时。兄弟排行二、五。十岁体弱,父先亡。(大运忌未)
正月:寅时。兄弟排行曰、六(性孤辞,爱好艺卫。(大运忌申)
正月:卯时。兄弟排行一、四。母先亡。(大运忌酉)
正月:辰时。兄弟徘行一一、五。二岁体弱、父母双全。(大运忌戌)
正月:巳时。二十岁以前有一大难,有养父母者为佳。(大运忌亥)
正月:午时。为人好礼仪,女性好修饰。(大运忌子)
正月:未时。女命婚姻多吵架,男命不受祖产,独自成功。(大运忌丑)
正月:申时。夜多啼哭,幼儿之时不好带(大运忌寅)
正月:酉时。无兄弟、多姊妹。得父母荫蔽。(大运忌卯)
正月:戌时。手足感情不佳、父先亡。(大运忌辰)
正月:亥时。智慧开早、幼时了了、中年平平、晚年发达、母先亡。(大运忌巳)

先看正则表达式([\u4e00-\u9fa5]{1,2})月:([\u4e00-\u9fa5]{1})时。(?<=时。)(.*)(?=。()
从下方这种下发,会将符合正则的情况,写入到group中,注意将你想要匹配的内容正则增加上括号,因为()是用来分组的
1
如果?<=?=这两个匹配之后和匹配之前的,就不需要加上括号,运行就是下面的结果
2
分取四段完整的正则是([\u4e00-\u9fa5]{1,2})月:([\u4e00-\u9fa5]{1})时。(?<=时。)(.*)(?=。()。((.*))
这个表达式还是有些绕,可以改成([\u4e00-\u9fa5]{1,2})月:([\u4e00-\u9fa5]{1})时。(.*)((.*)),因为分割符较为清晰,采取的方式也想对比较容易,然后根据group的序号进行取值即可
当然group需要并不是很好,如果有key、value的方式取值,可读岂不是更好,故而采取下面的模式进行处理。

assertion = '正月:午时。为人好礼仪,女性好修饰。(大运忌子)'
    reg = re.compile(r'(?P<month>[\u4e00-\u9fa5]+)月:(?P<hour>[\u4e00-\u9fa5]{1})时。(?P<assertion>.*)((?P<dayun>.*))')
    regm = reg.match(assertion)
    linebits = regm.groupdict()
    for k,v in linebits.items():
        print(k,v)

4 使用断言
大运里面的内容网站可能有错别字,那么这个时候需要用正则做一下筛选
取正确的内容,可以有很多种方式
使用.*(?:忌[子丑寅卯辰巳午未申酉戌亥])$,这里使用(?:pattern),他并不捕获分组
.*忌[子丑寅卯辰巳午未申酉戌亥]$
.*忌(?:[子丑寅卯辰巳午未申酉戌亥])$
大运(?=忌[子丑寅卯辰巳午未申酉戌亥]$)
这几种方式均可。
1
上面是筛选出正确的内容,如果想找到不符合的内容,使用的表达式如下,将正向匹配取反,大运(?!忌[子丑寅卯辰巳午未申酉戌亥]$),意思就是不以忌[子丑寅卯辰巳午未申酉戌亥]$结尾的内容

    # 换行
    mgs = re.split(r'\n',content)
    # 去除空行
    mgs = list(filter(None,mgs))
    #
    for mg in mgs:
        # 获取月份、时辰、断语
        # 获取大运
        pass

5 匹配符合规则的字符串
以八字开头和结尾,取其中,注意这里要用re.S因为做了换行

import re
import csv

try:
    file = open('../files/千里.txt','r',encoding='UTF-8')
    data = file.read()
    # pattern = r'(?<=(([甲乙丙丁庚戊己庚辛壬癸子丑寅卯辰巳午未申酉戌亥]{2}){4}))(.*?)(?=(([甲乙丙丁庚戊己庚辛壬癸子丑寅卯辰巳午未申酉戌亥]{2}){4}))'
    # pattern = r'甲子(.*?)甲子'
    pattern = r'(?<=(([甲乙丙丁庚戊己庚辛壬癸子丑寅卯辰巳午未申酉戌亥]{2}){4}))(.*?)(?=(([甲乙丙丁庚戊己庚辛壬癸子丑寅卯辰巳午未申酉戌亥]{2}){4}))'
    dg = re.findall(pattern, data,re.S)
    c_file = open('../files/千里.csv','a+',encoding='UTF-8',newline='')
    c_writer = csv.writer(c_file)
    for d in dg:
        ba = d[0]
        content = d[2].lstrip()
        year = ba[0:2]
        month = ba[2:4]
        day = ba[4:6]
        hour = ba[6:]
        bazi = '{} {} {} {}'.format(year,month,day,hour)
        c_writer.writerow([year,month,day,hour,bazi,content])
finally:
    if file:
        file.close()
    if c_file:
        c_file.close()

在这里插入图片描述
结果还是要稍作处理,并不是直接使用,但已经比我复制粘贴快多了
1

6 去掉一些特殊字符串

def remove_xa0(value):
    '''
    \xa0 是不间断空白符 &nbsp;
    '''
    return value.replace(u'\xa0',u'')

去掉'A型 [128]'中符合[128]条件的内容,用正则怎么写呢?re.sub的使用方法

a = '赵頔麦 [40] 、麦子、麦麦、今麦'
def test_01(a):
    p = re.compile('\[[\d\]]+')
    print(p.sub("",a))

7 js的一些正则样例
7.1 去空格
\s标识匹配任何空白字符,包括空格、制表符、换页符等等。等价于 [ \f\n\r\t\v]。并不算复杂,只要肯学

/**
 * 去掉右侧空格
 * @param {*} s 
 */
function rtrim(s){
  return s.replace(/(\s*$)/g, "");
}

7.2 提取给定的字符串
有一次跟C++的原函数对接,我只需要传递sql语句进去,返回的结果是{ "": "2"},没有key值,没法转成json,怎么取这个2呢,截取字符串?也很简单

let cn = result.match(/\d+/)[0]
  return parseInt(cn)
  • 2
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

warrah

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值