Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/joomla/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python RE(一句话,检查第一个字母是否区分大小写,其余字母是否区分大小写)_Python_Regex - Fatal编程技术网

Python RE(一句话,检查第一个字母是否区分大小写,其余字母是否区分大小写)

Python RE(一句话,检查第一个字母是否区分大小写,其余字母是否区分大小写),python,regex,Python,Regex,在下面的情况下,我想匹配字符串“Singapore”,其中“S”应该始终是大写,其余的单词可能是小写或大写。但在下面的文本中,字符串“s”是小写的,它在搜索条件中匹配。有谁能告诉我如何实施这一点 import re st = "Information in sinGapore " if re.search("S""(?i)(ingapore)" , st): print "matched

在下面的情况下,我想匹配字符串“Singapore”,其中“S”应该始终是大写,其余的单词可能是小写或大写。但在下面的文本中,字符串“s”是小写的,它在搜索条件中匹配。有谁能告诉我如何实施这一点

       import re       
            st = "Information in sinGapore "

            if re.search("S""(?i)(ingapore)" , st):
                print "matched"

Singapore => matched  
sIngapore => notmatched  
SinGapore => matched  
SINGAPORE => matched

正如所评论的,丑陋的方式是:

>>> re.search("S[iI][Nn][Gg][Aa][Pp][Oo][Rr][Ee]" , "SingaPore")
<_sre.SRE_Match object at 0x10cea84a8>
>>> re.search("S[iI][Nn][Gg][Aa][Pp][Oo][Rr][Ee]" , "Information in sinGapore")
更新 根据您的评论-您可以使用:

reg.search(s).group().startswith("S")
而不是:

reg.search(s).group()[0]==("S")

如果它看起来更可读。

您可以编写一个简单的lambda来生成难看但又完全重复的解决方案:

>>> leading_cap_re = lambda s: s[0].upper() + ''.join('[%s%s]' % 
                                                    (c.upper(),c.lower()) 
                                                        for c in s[1:])
>>> leading_cap_re("Singapore")
'S[Ii][Nn][Gg][Aa][Pp][Oo][Rr][Ee]'
对于多字城市,请定义字符串拆分版本:

>>> leading_caps_re = lambda s : r'\s+'.join(map(leading_cap_re,s.split()))
>>> print leading_caps_re('Kuala Lumpur')
K[Uu][Aa][Ll][Aa]\s+L[Uu][Mm][Pp][Uu][Rr]
那么您的代码可能就是:

if re.search(leading_caps_re("Singapore") , st):
    ...etc...
而RE的丑陋纯粹是内部的。

有趣的是

/((S)((?i)ingapore))/

在perl中做正确的事情,但在python中似乎不能按需要工作。为了公平起见,python文档清楚地说明了这一点,(?i)修改了整个regexp

,因为您想要根据捕获短语(我知道,唯一名称或几个名称之间是空格分隔的)设置GV代码,所以必须有一个步骤,在字典中根据捕获短语选择代码。
因此,很容易从这一步中获利,对短语中的第一个字母(必须大写)或第一个名字进行测试,而没有正则表达式能够做到这一点

我选择了某些条件来构成测试。例如,名字中的点不是强制性的,但大写字母是强制性的。这些条件在需要时很容易改变

编辑1 编辑2 我改进了代码。它更简短,可读性更强。
指令
assert(……])
用于验证字典的键是否格式正确

import re

def doot(x):
    return '\.?'.join(ch for ch in x) + '\.?'

def regexize(labels,doot=doot,
             wg2 = '(%s) *( %s)',wnog2 = '(%s)(%s)',
             ri = re.compile('(.(?!.*? )|[^ ]+)( ?) *(.+\Z)')):
    to_join = []
    modlabs = {}
    for K in labels.iterkeys():
        g1,g2,g3 = ri.match(K).groups()
        to_join.append((wg2 if g2 else wnog2)
                       % (doot(g1), doot(g3.lower())))
        modlabs[g1+g2+g3.lower()] = labels[K]
    return (re.compile('|'.join(to_join), re.I), modlabs)



def code(X,labels,regexize = regexize):
    reglab,modlabs = regexize(labels)
    for ma in reglab.finditer(X):
        a,b = tuple(x for x in ma.groups() if x)
        k = (a + b.lower()).replace('.','')
        GV = modlabs[k] if k in modlabs else '- bad match -'
        yield '  {!s:15}  {!s:^13}'.format(a+b, GV)

countries = {'Singapore':'SG','Austria':'AU',
             'Swiss':'CH','Chile':'CL',
             'Den LMM':'DN','LMM Den':'LM'}

assert(all('.' not in k and
          (k.count(' ')==1 or k[0].upper()==k[0])
          for k in countries))

s = ('  Singapore  SIngapore  SiNgapore  SinGapore'
     '  SI.Ngapore  SIngaPore  SinGaporE  SinGAPore'
     '  SINGaporE  SiNg.aPoR   singapore  sIngapore'
     '  siNgapore  sinGapore  sINgap.ore  sIngaPore'
     '  sinGaporE  sinGAPore  sINGaporE  siNgaPoRe'
     '    Austria    Aus.trIA    aUSTria    AUSTRiA'
     '  Den L.M.M     Den   Lm.M    DEn Lm.M.'
     '  DEN L.MM      De.n L.M.M.     Den LmM'
     '    L.MM   DEn      LMM DeN     LM.m  Den')

print '\n'.join(res for res in code(s,countries))

这是最好的答案:

(?-i:S)(?i)ingapore

作为证明:

“S”应该始终是大写。@wooble——不,它应该是
S[iI][nN][gG][aA][pP][oO][rR][eE]
,但这太难看了……必须有更好的方法……呃,对。读取失败。@wooble它不满足所有条件。在“S”之后可能有大写字母@eyquem你能在这方面帮我吗?谢谢你的回复。有没有其他方法来写同样的内容?因为如果我有一个长字符串,那么整个字符串的编写可能会有问题。我认为
reg.search(s)和reg.search(s.group()[0]=='S'
条件是可读的。@AdamMatan我认为你是对的-匹配所有较低的,然后仔细检查第一个字母是我能想到的Python的re的最好方法。…@Adam Matan感谢你的回答。我如何使用if-else循环实现相同的功能。例如,如果它匹配singapore,我想将全局vaiable GV设置为SG elif匹配australia将GV设置为AU等等…你没有错,但是正则表达式太难看且不可读。有更好的方法编写正则表达式,并支持其功能。@NHAHDH-我不是建议OP使用由
开头的大写字母
创建的文字字符串,而是在内部使用难看的re字符串,如中所示我的编辑。我删除了我的否决票,因为我误解了
re
中“flag”组的工作原理。它在整个表达式中的应用方式使得它几乎毫无用处。它工作得很好。但是在上面的“Singapore”中,我想看到“S”是大写字母和“ingapore”可以是小写字母或大写字母,也可以两者兼有。但上面的情况只适用于“Singapore”。我知道在perl中,我们使用regex,比如“S”“(?i)ingapore”.输出应为新加坡SG新加坡SG新加坡SG新加坡SG新加坡新加坡SG新加坡-不匹配-新加坡-不匹配-以及项目的结果和案例。“M”、“LMM DeN”等。对于“DeN Lm.M”这个案例,“DeN”应该是区分大小写的,“Lm.N”可能在任何一个案例中。对于“LMM DeN”这个案例,“LMM”应该区分大小写,“De”可能在任何一个案例中,“N”也应该区分大小写。什么!!?对于“LMM DeN”
LMM
必须区分大小写(没关系,我的代码就是这样做的)而
De
在任何情况下都是可以接受的,但是
N
应该区分大小写?!为什么?事实上,我不需要知道为什么,我需要知道一般规则,而不是一个接一个地添加规则,否则过程将是永久的。请完全澄清规则。
import re

def doot(x):
    return '\.?'.join(ch for ch in x) + '\.?'

def regexize(labels,doot=doot,
             wg2 = '(%s) *( %s)',wnog2 = '(%s)(%s)',
             ri = re.compile('(.(?!.*? )|[^ ]+)( ?) *(.+\Z)')):
    to_join = []
    modlabs = {}
    for K in labels.iterkeys():
        g1,g2,g3 = ri.match(K).groups()
        to_join.append((wg2 if g2 else wnog2)
                       % (doot(g1), doot(g3.lower())))
        modlabs[g1+g2+g3.lower()] = labels[K]
    return (re.compile('|'.join(to_join), re.I), modlabs)



def code(X,labels,regexize = regexize):
    reglab,modlabs = regexize(labels)
    for ma in reglab.finditer(X):
        a,b = tuple(x for x in ma.groups() if x)
        k = (a + b.lower()).replace('.','')
        GV = modlabs[k] if k in modlabs else '- bad match -'
        yield '  {!s:15}  {!s:^13}'.format(a+b, GV)

countries = {'Singapore':'SG','Austria':'AU',
             'Swiss':'CH','Chile':'CL',
             'Den LMM':'DN','LMM Den':'LM'}

assert(all('.' not in k and
          (k.count(' ')==1 or k[0].upper()==k[0])
          for k in countries))

s = ('  Singapore  SIngapore  SiNgapore  SinGapore'
     '  SI.Ngapore  SIngaPore  SinGaporE  SinGAPore'
     '  SINGaporE  SiNg.aPoR   singapore  sIngapore'
     '  siNgapore  sinGapore  sINgap.ore  sIngaPore'
     '  sinGaporE  sinGAPore  sINGaporE  siNgaPoRe'
     '    Austria    Aus.trIA    aUSTria    AUSTRiA'
     '  Den L.M.M     Den   Lm.M    DEn Lm.M.'
     '  DEN L.MM      De.n L.M.M.     Den LmM'
     '    L.MM   DEn      LMM DeN     LM.m  Den')

print '\n'.join(res for res in code(s,countries))
(?-i:S)(?i)ingapore