Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/356.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中的字符串_Python_Regex_Types - Fatal编程技术网

“确定”;“价值类型”;来自python中的字符串

“确定”;“价值类型”;来自python中的字符串,python,regex,types,Python,Regex,Types,我试图用python编写一个函数,它将确定字符串中的值的类型;比如说 如果in字符串为1或0或True或False,则值为位 如果in字符串为0-9*,则值为INT 如果字符串中的值为0-9+。0-9+则该值为浮点值 如果在字符串中为stg,则更多(文本等)值为文本 到目前为止,我有stg喜欢 def dataType(string): odp='' patternBIT=re.compile('[01]') patternINT=re.compile('[0-9]+') patter

我试图用python编写一个函数,它将确定字符串中的值的类型;比如说

如果in字符串为1或0或True或False,则值为位

如果in字符串为0-9*,则值为INT

如果字符串中的值为0-9+。0-9+则该值为浮点值

如果在字符串中为stg,则更多(文本等)值为文本

到目前为止,我有stg喜欢

def dataType(string):

 odp=''
 patternBIT=re.compile('[01]')
 patternINT=re.compile('[0-9]+')
 patternFLOAT=re.compile('[0-9]+\.[0-9]+')
 patternTEXT=re.compile('[a-zA-Z0-9]+')
 if patternTEXT.match(string):
     odp= "text"
 if patternFLOAT.match(string):
     odp= "FLOAT"
 if patternINT.match(string):
     odp= "INT"
 if patternBIT.match(string):
     odp= "BIT"

 return odp 

但是我不太擅长在python中使用正则表达式。你能告诉我,我做错了什么吗?例如,它对2010-00-10不起作用,2010-00-10应该是文本,但是是INT或20.90,应该是float,但是是INT,在你走太远的正则表达式之前,你考虑过使用

示例:

In [35]: ast.literal_eval('1')
Out[35]: 1

In [36]: type(ast.literal_eval('1'))
Out[36]: int

In [38]: type(ast.literal_eval('1.0'))
Out[38]: float

In [40]: type(ast.literal_eval('[1,2,3]'))
Out[40]: list
不妨使用Python为您解析它

好的,这里有一个更大的例子:

import ast, re
def dataType(str):
    str=str.strip()
    if len(str) == 0: return 'BLANK'
    try:
        t=ast.literal_eval(str)

    except ValueError:
        return 'TEXT'
    except SyntaxError:
        return 'TEXT'

    else:
        if type(t) in [int, long, float, bool]:
            if t in set((True,False)):
                return 'BIT'
            if type(t) is int or type(t) is long:
                return 'INT'
            if type(t) is float:
                return 'FLOAT'
        else:
            return 'TEXT' 



testSet=['   1  ', ' 0 ', 'True', 'False',   #should all be BIT
         '12', '34l', '-3','03',              #should all be INT
         '1.2', '-20.4', '1e66', '35.','-   .2','-.2e6',      #should all be FLOAT
         '10-1', 'def', '10,2', '[1,2]','35.9.6','35..','.']

for t in testSet:
    print "{:10}:{}".format(t,dataType(t))
输出:

   1      :BIT
 0        :BIT
True      :BIT
False     :BIT
12        :INT
34l       :INT
-3        :INT
03        :INT
1.2       :FLOAT
-20.4     :FLOAT
1e66      :FLOAT
35.       :FLOAT
-   .2    :FLOAT
-.2e6     :FLOAT
10-1      :TEXT
def       :TEXT
10,2      :TEXT
[1,2]     :TEXT
35.9.6    :TEXT
35..      :TEXT
.         :TEXT
如果你确实必须有一个正则表达式解决方案,它会产生相同的结果,这里是:

def regDataType(str):
    str=str.strip()
    if len(str) == 0: return 'BLANK'

    if re.match(r'True$|^False$|^0$|^1$', str):
        return 'BIT'
    if re.match(r'([-+]\s*)?\d+[lL]?$', str): 
        return 'INT'
    if re.match(r'([-+]\s*)?[1-9][0-9]*\.?[0-9]*([Ee][+-]?[0-9]+)?$', str): 
        return 'FLOAT'
    if re.match(r'([-+]\s*)?[0-9]*\.?[0-9][0-9]*([Ee][+-]?[0-9]+)?$', str): 
        return 'FLOAT'

    return 'TEXT' 

然而,我不能推荐正则表达式而不是ast版本;让Python来解释它认为这些数据类型是什么,而不是用正则表达式来解释它们…

您也可以使用json

import json
converted_val = json.loads('32.45')
type(converted_val)
输出

type <'float'>
它匹配,因此
odp
设置为“text”

然后,您的脚本执行以下操作:

if patternFLOAT.match(str_obj):
不匹配,
odp
仍然等于“text”

部分匹配
odp
设置为“INT”

由于match返回部分匹配,因此将计算多个
if
语句,最后一个计算语句将确定在
odp
中返回哪个字符串

您可以执行以下几项操作之一:

  • 重新排列if语句的顺序,以便最后一个匹配的语句是正确的

  • 对于其余的
    if
    语句,请使用
    if
    elif
    ,以便只计算要匹配的第一条语句

  • 检查以确保匹配对象与整个字符串匹配:

    ...
    match = patternINT.match(str_obj)
    if match:
        if match.end() == match.endpos:
            #do stuff
    ...
    

  • 你说你用这些作为输入:

    • 2010-00-10(是整数,不是文本)
    • 20.90(为整数,非浮动)
    您的原始代码:

    def dataType(string):
    
     odp=''
     patternBIT=re.compile('[01]')
     patternINT=re.compile('[0-9]+')
     patternFLOAT=re.compile('[0-9]+\.[0-9]+')
     patternTEXT=re.compile('[a-zA-Z0-9]+')
     if patternTEXT.match(string):
         odp= "text"
     if patternFLOAT.match(string):
         odp= "FLOAT"
     if patternINT.match(string):
         odp= "INT"
     if patternBIT.match(string):
         odp= "BIT"
    
     return odp 
    
    问题 您的
    if
    语句将按顺序执行-即:

    if patternTEXT.match(string):
        odp= "text"
    if patternFLOAT.match(string):
        odp= "FLOAT"
    if patternINT.match(string)
        odp= "INT"
    if patternBIT.match(string):
        odp= "BIT"
    
    “2010-00-10”匹配您的文本模式,但随后它将尝试匹配您的浮点模式(失败,因为没有
    ),然后匹配
    int
    模式,该模式有效,因为它确实包含
    [0-9]+

    你应使用:

    if patternTEXT.match(string):
        odp = "text"
    elif patternFLOAT.match(string):
        ...
    
    虽然对于您的情况,您可能希望从更具体到不太具体,因为正如您所看到的,文本内容也可能是int(反之亦然)。您还需要改进正则表达式,因为“文本”模式只匹配字母数字输入,而不匹配特殊符号

    虽然我更喜欢AST解决方案,但我会提出自己的建议:

    def get_type(string):
    
        if len(string) == 1 and string in ['0', '1']:
            return "BIT"
    
        # int has to come before float, because integers can be
        # floats.
        try:
            long(string)
            return "INT"
        except ValueError, ve:
            pass
    
        try:
            float(string)
            return "FLOAT"
        except ValueError, ve:
            pass
    
        return "TEXT"
    
    运行示例:

    In [27]: get_type("034")
    Out[27]: 'INT'
    
    In [28]: get_type("3-4")
    Out[28]: 'TEXT'
    
    
    In [29]: get_type("20.90")
    Out[29]: 'FLOAT'
    
    In [30]: get_type("u09pweur909ru20")
    Out[30]: 'TEXT'
    
    答复

    例如,它不适用于2010-00-10,应该是文本,但是 是INT或20.90,应该是float,但是是INT

    >>重新导入
    >>>patternINT=re.compile('[0-9]+'))
    >>>打印Patternit.match('2010-00-10')
    >>>patternINT=re.compile(“[0-9]+$”)
    >>>打印模式匹配('2010-00-10')
    没有一个
    >>>打印patternit.match('2010')
    

    不要忘记
    $
    来限制字符串的结尾。

    您的输入是什么样子的?请记住,
    match
    仅在字符串开头匹配。您的代码什么时候不起作用?请发布您试图解析的文件的示例,以便我们可以复制错误并按预期检查解决方案的工作情况。您不需要使用正则表达式-您可以尝试使用
    int将字符串转换/强制转换为其他类型()
    float()
    。对于位,您可以检查字符串长度是否为1,并且在(0,1)中是否为
    。然后用
    try except
    包装转换。但这与正则表达式无关。我已更新了原始的postBut
    类型(json.loads('1'))
    返回
    int
    而OP想要
    bool
    @San4ez:you're对,这是一个特殊情况。就像“bit”一样,@JoelCornett
    json
    模块在那里并不明显+1@San4ez:谢谢:)另外,我意识到我的答案实际上并没有回答OP的问题“我做错了什么?”。编辑以包含该值。感谢您的回答,但我不知道如何使用ast来确定“位”和“文本”值(特别是对于文本-它给了我一个错误,当我调用ast.literal('string')@Johnzzz时,请尝试
    ast.literal('string'))
    。最外面的引号创建一个字符串,但它不会被
    ast.literal
    解析为字符串,除非它周围还有引号。@johnzz,然后测试“位”很容易;只需检查值是否在集合中((真,假))
    。(
    0
    1
    通过了这个测试,至少在Python 2.6中通过了
    True
    False
    ,在新版本中可能会有所不同。)@carrot top,非常感谢。我并不明确地想使用正则表达式,但这似乎是一个很好的示例,我可以在其中学习正则表达式:)因此,非常感谢您对
    re.match
    的回答。您不需要初始的
    ^
    锚定。此方法已从字符串开始搜索。无论如何,您都需要带有
    re.search
    Read+1的锚定。
    def get_type(string):
    
        if len(string) == 1 and string in ['0', '1']:
            return "BIT"
    
        # int has to come before float, because integers can be
        # floats.
        try:
            long(string)
            return "INT"
        except ValueError, ve:
            pass
    
        try:
            float(string)
            return "FLOAT"
        except ValueError, ve:
            pass
    
        return "TEXT"
    
    In [27]: get_type("034")
    Out[27]: 'INT'
    
    In [28]: get_type("3-4")
    Out[28]: 'TEXT'
    
    
    In [29]: get_type("20.90")
    Out[29]: 'FLOAT'
    
    In [30]: get_type("u09pweur909ru20")
    Out[30]: 'TEXT'
    
    >>> import re
    >>> patternINT=re.compile('[0-9]+')
    >>> print patternINT.match('2010-00-10')
    <_sre.SRE_Match object at 0x7fa17bc69850>
    >>> patternINT=re.compile('[0-9]+$')
    >>> print patternINT.match('2010-00-10')
    None
    >>> print patternINT.match('2010')
    <_sre.SRE_Match object at 0x7fa17bc69850>