简体   繁体   English

Python - pyparsing unicode 字符

[英]Python - pyparsing unicode characters

:) I tried using w = Word(printables), but it isn't working. :) 我尝试使用 w = Word(printables),但它不起作用。 How should I give the spec for this.我应该如何为此提供规范。 'w' is meant to process Hindi characters (UTF-8) 'w' 用于处理印地语字符 (UTF-8)

The code specifies the grammar and parses accordingly.代码指定语法并相应地解析。

671.assess  :: अहसास  ::2
x=number + "." + src + "::" + w + "::" + number + "." + number

If there is only english characters it is working so the code is correct for the ascii format but the code is not working for the unicode format.如果只有英文字符它正在工作,所以代码对于 ascii 格式是正确的,但代码对于 unicode 格式不起作用。

I mean that the code works when we have something of the form 671.assess :: ahsaas ::2我的意思是当我们有 671.assess :: ahsaas ::2 形式的东西时,代码可以工作

ie it parses words in the english format, but I am not sure how to parse and then print characters in the unicode format.即它以英文格式解析单词,但我不确定如何解析然后以 unicode 格式打印字符。 I need this for English Hindi word alignment for purpose.我需要这个用于英语印地语单词对齐。

The python code looks like this: python 代码如下所示:

# -*- coding: utf-8 -*-
from pyparsing import Literal, Word, Optional, nums, alphas, ZeroOrMore, printables , Group , alphas8bit , 
# grammar 
src = Word(printables)
trans =  Word(printables)
number = Word(nums)
x=number + "." + src + "::" + trans + "::" + number + "." + number
#parsing for eng-dict
efiledata = open('b1aop_or_not_word.txt').read()
eresults = x.parseString(efiledata)
edict1 = {}
edict2 = {}
counter=0
xx=list()
for result in eresults:
  trans=""#translation string
  ew=""#english word
  xx=result[0]
  ew=xx[2]
  trans=xx[4]   
  edict1 = { ew:trans }
  edict2.update(edict1)
print len(edict2) #no of entries in the english dictionary
print "edict2 has been created"
print "english dictionary" , edict2 

#parsing for hin-dict
hfiledata = open('b1aop_or_not_word.txt').read()
hresults = x.scanString(hfiledata)
hdict1 = {}
hdict2 = {}
counter=0
for result in hresults:
  trans=""#translation string
  hw=""#hin word
  xx=result[0]  
  hw=xx[2]
  trans=xx[4]
  #print trans
  hdict1 = { trans:hw }
  hdict2.update(hdict1)

print len(hdict2) #no of entries in the hindi dictionary
print"hdict2 has been created"
print "hindi dictionary" , hdict2
'''
#######################################################################################################################

def translate(d, ow, hinlist):
   if ow in d.keys():#ow=old word d=dict
    print ow , "exists in the dictionary keys"
        transes = d[ow]
    transes = transes.split()
        print "possible transes for" , ow , " = ", transes
        for word in transes:
            if word in hinlist:
        print "trans for" , ow , " = ", word
                return word
        return None
   else:
        print ow , "absent"
        return None

f = open('bidir','w')
#lines = ["'\
#5# 10 # and better performance in business in turn benefits consumers .  # 0 0 0 0 0 0 0 0 0 0 \
#5# 11 # vHyaapaar mEmn bEhtr kaam upbhOkHtaaomn kE lIe laabhpHrdd hOtaa hAI .  # 0 0 0 0 0 0 0 0 0 0 0 \
#'"]
data=open('bi_full_2','rb').read()
lines = data.split('!@#$%')
loc=0
for line in lines:
    eng, hin = [subline.split(' # ')
                for subline in line.strip('\n').split('\n')]

    for transdict, source, dest in [(edict2, eng, hin),
                                    (hdict2, hin, eng)]:
        sourcethings = source[2].split()
        for word in source[1].split():
            tl = dest[1].split()
            otherword = translate(transdict, word, tl)
            loc = source[1].split().index(word)
            if otherword is not None:
                otherword = otherword.strip()
                print word, ' <-> ', otherword, 'meaning=good'
                if otherword in dest[1].split():
                    print word, ' <-> ', otherword, 'trans=good'
                    sourcethings[loc] = str(
                        dest[1].split().index(otherword) + 1)

        source[2] = ' '.join(sourcethings)

    eng = ' # '.join(eng)
    hin = ' # '.join(hin)
    f.write(eng+'\n'+hin+'\n\n\n')
f.close()
'''

if an example input sentence for the source file is:如果源文件的示例输入语句是:

1# 5 # modern markets : confident consumers  # 0 0 0 0 0 
1# 6 # AddhUnIk baajaar : AshHvsHt upbhOkHtaa .  # 0 0 0 0 0 0 
!@#$%

the ouptut would look like this :-输出看起来像这样:-

1# 5 # modern markets : confident consumers  # 1 2 3 4 5 
1# 6 # AddhUnIk baajaar : AshHvsHt upbhOkHtaa .  # 1 2 3 4 5 0 
!@#$%

Output Explanation:- This achieves bidirectional alignment.输出说明:- 这实现了双向对齐。 It means the first word of english 'modern' maps to the first word of hindi 'AddhUnIk' and vice versa.这意味着英语“现代”的第一个词映射到印地语“AddhUnIk”的第一个词,反之亦然。 Here even characters are take as words as they also are an integral part of bidirectional mapping.这里甚至字符也被当作单词,因为它们也是双向映射的一个组成部分。 Thus if you observe the hindi WORD '.'因此,如果您观察印地语单词 '.' has a null alignment and it maps to nothing with respect to the English sentence as it doesn't have a full stop.有一个空对齐,它相对于英语句子没有映射,因为它没有句号。 The 3rd line int the output basically represents a delimiter when we are working for a number of sentences for which your trying to achieve bidirectional mapping.当我们正在处理您试图实现双向映射的许多句子时,输出中的第三行基本上代表一个分隔符。

What modification should i make for it to work if the I have the hindi sentences in Unicode(UTF-8) format.如果我有 Unicode(UTF-8) 格式的印地语句子,我应该做哪些修改才能使其工作。

Pyparsing's printables only deals with strings in the ASCII range of characters. Pyparsing 的printables仅处理 ASCII 字符范围内的字符串。 You want printables in the full Unicode range, like this:您需要完整 Unicode 范围内的可打印文件,如下所示:

unicodePrintables = u''.join(unichr(c) for c in xrange(sys.maxunicode) 
                                        if not unichr(c).isspace())

Now you can define trans using this more complete set of non-space characters:现在您可以使用这组更完整的非空格字符来定义trans

trans = Word(unicodePrintables)

I was unable to test against your Hindi test string, but I think this will do the trick.我无法针对您的印地语测试字符串进行测试,但我认为这可以解决问题。

(If you are using Python 3, then there is no separate unichr function, and no xrange generator, just use: (如果您使用的是 Python 3,则没有单独的 unichr 函数,也没有 xrange 生成器,只需使用:

unicodePrintables = ''.join(chr(c) for c in range(sys.maxunicode) 
                                        if not chr(c).isspace())

EDIT:编辑:

With the recent release of pyparsing 2.3.0, new namespace classes have been defined to give printables , alphas , nums , and alphanums for various Unicode language ranges.随着最近发布的 pyparsing 2.3.0,已经定义了新的命名空间类来为各种 Unicode 语言范围提供printablesalphasnumsalphanums

import pyparsing as pp
pp.Word(pp.pyparsing_unicode.printables)
pp.Word(pp.pyparsing_unicode.Devanagari.printables)
pp.Word(pp.pyparsing_unicode.देवनागरी.printables)

As a general rule, do not process encoded bytestrings: make them into proper unicode strings (by calling their .decode method) as soon as possible, do all of your processing always on unicode strings, then, if you have to for I/O purposes, .encode them back into whatever bytestring encoding you require.作为一般规则,处理编码的字节串:让他们到适当的Unicode字符串(通过调用其.decode法)尽快,做你的处理总是Unicode字符串,然后,如果你要为I / O目的, .encode它们编码回您需要的任何字节.encode编码。

If you're talking about literals, as it seems you are in your code, the "as soon as possible" is at once : use u'...' to express your literals.如果你在谈论文字,就像你在你的代码中一样,“尽快”是一次:使用u'...'来表达你的文字。 In a more general case, where you're forced to do I/O in encoded form, it's immediately after input (just as it's immediately before output if you need to perform output in a specific encoded form).在更一般的情况下,您被迫以编码形式执行 I/O,它紧接在输入之后(就像如果您需要以特定编码形式执行输出,则紧接在输出之前)。

I Was searching about french unicode chars and fall on this question.我正在搜索法语 unicode 字符并落在这个问题上。 If you search french or other latin accents, with pyparsing 2.3.0 you can use:如果您搜索法语或其他拉丁口音,使用pyparsing 2.3.0您可以使用:

>>> pp.pyparsing_unicode.Latin1.alphas
'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzªµºÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõöøùúûüýþÿ'

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM