栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

【NLP方向】【万时计划】16-22

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

【NLP方向】【万时计划】16-22

基础知识部分 词法分析

包括分词、词性标注、命名实体识别和词义消歧。使用词性标注便于判定每个词的语法范畴。词义标注、词义消歧主要解决多语境下的词义问题,因为在多语境下一个词可能会拥有很多含义,但在固定情境下意思往往是确定的。在中文情境下词法分析是最核心的一部分,只有做好分词工作,剩下的工作才能顺利进行。

词法分析的实现主要通过基于规则、基于统计、基于机器学习的方法。

lexical analysis是计算及科学中将字符序列转换为标记(token)序列的过程。进行词法分析的程序或者函数即为词法分析器简称lexer词法分析器一般以函数形式存在,供语法分析器调用。

      b=1
00
101:a=2*(1+3)
       IF(b>10) THEN
             a=1
       ELSE  IF(b>=5) THEN
             a=2
       ELSE
             GOTO 101

#coding=utf-8
import sys
import string
key_word = ['IF','THEN','ELSE','GOTO']         #定义关键词
operator  = ['=','+','>=','*','>']             #定义运算符
delimiters = [':','(',')']                     #定义界符

#预处理函数,对例程进行预处理,去掉多余的空格、注释
def preprocess(file_name):
          try:                                         #try except 使程序不会因为异常而中断
                fp_read = open(file_name,'r')          #打开需要分析的文件
                fp_write = open('preprocess.txt','w')
                sign = 0                               #每当上一个字符为空格时,将sign变为1,通过这样来保证每个需要空格的地方不会有多余的空格
                while True:
                      read = fp_read.readline()        #循环读取每一行字符 
                if not read:
                      break                            #如果没有读取到任何东西直接结束循环
                length = len(read)                     #获得当前字符串的长度
                i = -1
                while i < length - 1:                  #循环读取每个字符
                         i+=1
                if read[i] == ' ':    
                    if sign == 1:                      #读取到空格,如果sign为1说明上一个字符也是空格,那个可以忽略当前空格
                        continue
                    else:                              #如果sign不为1,说明上一个字符不是空格,那么就输出当前空格
                        sign = 1
                        fp_write.write(' ')
                elif read[i] == 't':                  #同上读取到空格的操作,对于水平制表符(tab)同样输出为一个空格,如果已经输出过一个空格了那就选择跳过
                    if sign == 1:
                        continue
                    else:
                        sign = 1
                        fp_write.write('')
                elif read[i] == 'n':                  #同上读取到水平制表符(tab)的操作
                    if sign == 1:
                        continue
                    else:
                        sign = 1
                        fp_write.write(' ')
                elif read[i] == '/' and read[i+1] == '*':    #如果读取到/* 即注释
                        i = i + 2                       #从星号之后的第一个字符开始遍历直到读取到下一对注释
                        while True:
                            if read[i] == '*' and read[i+1] == '/':
                                break
                            i = i + 1
                        i = i + 1                       #遍历完之后i停留在左斜杠,所以需要+1达到下一个字符
                elif read[i] == '\':                   #如果读取到续行符,之所以是双斜杠因为右斜杠是转义字符,双右斜杠等于单右斜杠,即续行符
                    break
                else:       #除了以上这些就直接输出字符就好
                    fp_write.write(read[i])
                    sign = 0
                fp_write.write('#')#在最后输出一个井号
            except Exception:
                print('Errors')

# K:关键字 I:标识符 C:常数 O:运算符 P:界符 L:标号
def process(file_name):
    try:
        fp_read=open(file_name,'r')        #打开预处理之后得到的文件
        fp_write=open('result.txt','w')     #打开一个新的文件,为了将得到的二元式表输入进去
        lines = fp_read.readlines()          #依旧是按行读取
        i = -1
        for line in lines:                         #逐行遍历
            length = len(line)                 #获得当前行字符长度为了遍历每个字符
            while  i < length - 1:
                i+=1
                if line[i] == ' ':              #当前字符为空格,直接跳过
                    continue
                if line[i] in delimiters:       #当前字符在最开始定义的界符集中,那么就直接输出(P,当前字符)
                    print('(P,',line[i],')',file=fp_write)
                    continue
                if line[i] in operator:        #当前字符在运算符集中
                    if line[i-1] in operator:    #判断运算符,祥见程序之后注释(1)
                        continue
                    print('(O,',end='',file=fp_write)   #end=''实现print不换行,file=fp_write实现将print的内容输出到文件中
                    if line[i+1] in operator:
                        print(line[i],line[i+1],')',sep='',file=fp_write) #sep=''实现print连续输出不加空格,为了输出>=而不是> =
                    else:
                        print(line[i],')',file=fp_write)
                    continue
                if line[i-1].isdigit():        #判断数字,祥见程序之后注释(2)
                    continue
                if line[i].isdigit():
                    t = i
                    while line[i].isdigit():
                        i+=1
                    if line[i] == ':' or line[i] == '#':
                        print('(L,',end='',file=fp_write)
                    else:
                        print('(C,',end='',file=fp_write)
                    i = t
                    while line[i].isdigit():
                        print(line[i],end='',file=fp_write)
                        i+=1
                    print(')',file=fp_write)
                    i-=1
                    continue
                j = 0
                temp = ''              #判断关键词及标识符,详见程序之后注释(3)
                while True:
                    if  line[i] == ' ' or line[i] in operator or line[i] in delimiters:
                        break
                    else:
                        j+=1
                    i+=1
                    if i > length-1:
                        break
                temp = line[i-j:i]
                if temp in key_word:
                    print('(K,',temp,')',file=fp_write)
                else:
                    if temp == '#':
                       break
                    print('(I,',temp,')',file=fp_write)
                i-=1
    except Exception:
        print('Error')

def main():
      preprocess('source.txt')
      process('preprocess.txt')
if __name__=='__main__':
      main()

  1. 判断运算符,整体思路是当识别到当前字符是运算符的时候,判断下一个字符是否也是运算符,如果是运算符的话,就连续输出两个运算符,如果不是,就单独输出,需要加一个if判断上一个字符是否为运算符,若是,则直接跳过,因为如果是的话当前运算符肯定已经输出过了。
  2. 判断数字,在程序中数字分两种,一是给变量赋的值,二是程序段前的标号,通过观察这两种数字前后紧邻的符号来确定类型。当读取到数字的时候,程序会先保存一下当前的i值,然后循环一次得到当前数字是几位数,以便得到最后一位数之后是冒号或者#来判断当前数字是标号还是常数,之所以保存了i的值,就是为了在判断完成之后,让i的值复位,然后重新循环读取整个数字。在读取完整个数字之后让i-1
  3. 判断关键词和标识符,定义j来表示关键词或者标识符长度,temp为空的字符串,当遇到空格、运算符、界符就跳出循环line[i-j:i]即为从i-j到i对应的字符串,也就是遍历遇到要么是关键词要么是标识符的字符串,如果这个字符串在key_word数组中,那么就是关键词,否则就是标识符。
项目部分 python防止程序中断

每次加载之前都需要将之前搜索过的*号加载进来,进行去重。

def have_already_search_no(out_put_tb):
    my_insert = con_oracle()
    conn_insert = my_insert[0]
    cur_insert = my_insert[1]
    
    cmd = "select distinct *号 from xyz." + out_put_tb
    cur_insert.execute(cmd)
    all_no = set([i[0] for i in cur_insert])
    print('已处理*号加载完毕!')
    cur_insert.close()
    conn_insert.close()
    
    return all_no

python中set()集合,里面不含重复元素,接收一个list作为参数。可以使用add(key)向集合中添加元素,重复元素自动过滤。可以通过remove(key)方法删除元素。set还可以像数学上那样求交集和并集。

list1 = ['a', 'b', 'zhang', 'kang']
list2 = ['a', 'b', 'c', 'd']
s1 = set(list1)
s2 = set(list2)
#交集使用&
s3 = s1&s2
#并集使用|
s4 = s1|s2

获取已导入的*号

def import_info():
    my_con = con_oracle()
    conn = my_con[0]
    cur = my_con[1]
    cmd = "select **人, *号 from 库.zhaiyao where *号 is not null and **人 is not null"
    cur.execute(cmd)
    all_no = []
    for i in cur:
         pr = i[0]
         no = i[1]
        all_no.append(no)
     cur.close()
     conn.close() 
**人地址和所有 所在地分析

具体逻辑:**人如有注册地,则使用该地址,如果没有则提取出 *告的省市县地址,然后对??提取省市县地址信息进行比对分为两种:1.同省不同市 2.不同省不同市。

def BG_addr_analysis(all_info, BG, reg_addr_info):
    result1 = [] #同省不同市
    result2 = [] #不同省市
    BG_addr_info1 = ['', '', '']
    BG_addr_info2 = ['', '', '']
    if reg_addr_info:
        reg_addr = reg_addr_info[0][0]
        BG_addr_info1 = person_address(reg_addr)
     BG_addr_info2 = person_address(BG)
     BG_addr_info1_clean = [i for i in BG_addr_info1 if i]
     BG_addr_info2_clean = [i for i in BG_addr_info2 if i]
    #先注册地提取一次省市,然后??名字提取一次省市,比较一下哪个信息提取得多就用哪个
    if len(BG_addr_info1_clean) >= len(BG_addr_info2_clean):
        final_addr_info = BG_addr_info1
    else:
        final_addr_info = BG_addr_info2
        
     if len(all_info) == 0:
        return [], []
    else:
        for info in all_info:
            C_h1 = KillNone(info[4])#做出????单位
            C_h2 = KillNone(info[5])#执行??
            
            C_h_final = C_h2
            if not C_h_final:
                C_h_final = C_h1
            C_h_a = person_address(C_h_final)
            C_h_a_prov = C_h_a[0]
            C_h_a_city = C_h_a[1]
            BG_a_prov = final_addr_info[0]
            BG_a_city = final_addr_info[1]
            
            if C_h_a_city != BG_a_city:
                if C_h_a_prov == BG_a_prov:
                    result1.append(info)
                else:
                    result2.append(info)
     return result1, result2
‘sep’.join(seq)
def get_p_attr(com):
    attr1 = get_c_label(com)
    attr_list = [attr1]
    attr_label = '_'.join(attr_list)
    return attr_label

sep:分隔符,可以为空

seq:要链接的元素序列、字符串、元组、字典

以sep作为分隔符,将seq所有元素合并成为一个新的字符串。返回一个以分隔符sep连接各个元素后生成的字符串。

sorted()

all_J_time_info1 = sorted(all_J_time_info, key=lambda x: x[1])

sort函数:对python中的列表进行排序,该函数在原空间上进行操作,对列表本身进行修改,不反回副本:

L.sort(cmp=None, key=None, reverse=False)

sorted函数比sort函数要强大许多,sorted可以对所有可迭代类型数据进行排序并返回新的已排序列表。

1.比较函数经常会用到lambda,lambda表达式通常是在需要一个函数,但是又不想费神去命名一个函数的场合下使用,也就是指匿名函数。比如对元组组成的列表中某一项进行排序;

students = [('john', 'A', 15), ('jane', 'B', 12), ('dave', 'B', 10)]
sorted(students, key = lambda student : student[2]) #sort by age

2.比较函数经常会用到operator.itemgetter函数

operator模块提供的itemgetter函数用于获取对象的哪些维的数据,参数为一些序号。

operator.itemgetter函数获取的不是值,而是定义了一个函数通过该函数作用到对象上才能获取值。

sorted函数用来排序,sorted(iterable[, cmp[, key[, reverse]]]).其中key的参数为一个函数或者lambda函数。所以itemgetter可以用来当key的参数。

a = [('join','A', 15), ('jane', 'B', 12), ('dave', 'B', 10)]
sorted(students, key=operator.itemgetter(1,2))

3.可迭代元素经常会用到items。这是字典中的一个方法,返回由元组组成的列表。

iter()

在python中iter()函数的功能是:接受一个可迭代对象,将其转换成一个迭代器。

a = [1,2,3]
a_iter = iter(a)
print(a_iter)

高阶用法:传入两个参数:使用常规的函数或者任意可调用对象创建迭代器。这样使用时,第一个参数必须是可调用的对象(无参数调用),用于不断调用产出值。第二个是哨符,这是标记值,当可调用对象返回这个值的时候,触发迭代器抛出的Stoplteration异常,程序结束第一个参数中的对象不断产出值,当产出的值和第二个参数是一样的时候,停止产出。

from random import randit
def d10():
    return randint(1, 10)
#随机产生1~10之间的数,遇到5即停止
for i in iter(d10, 5):
    print(i)
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/948280.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号