Joh*_*zzz 3 python regex types
我正在尝试在python中编写一个函数,它将确定字符串中的值的类型; 例如
如果in string为1或0或True或False,则该值为BIT
如果in string为0-9*,则值为INT
如果在字符串中是0-9 + .0-9 +,则该值为float
如果在字符串中是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
Run Code Online (Sandbox Code Playgroud)
但是我在python中使用正则表达式并不是很熟练.你能告诉我,我做错了什么?例如,它不适用于2010-00-10,它应该是Text,但是INT或20.90,它应该是float但是是int
the*_*olf 17
在你走到正则表达式路线之前,你考虑过使用ast.literal_eval
例子:
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
Run Code Online (Sandbox Code Playgroud)
也可以使用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))
Run Code Online (Sandbox Code Playgroud)
输出:
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
Run Code Online (Sandbox Code Playgroud)
如果你肯定有一个正则表达式解决方案,产生相同的结果,这里是:
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'
Run Code Online (Sandbox Code Playgroud)
我不能推荐高级版本的正则表达式; 让Python解释它认为这些数据类型的内容而不是用正则表达式解释它们...
您也可以使用json。
import json
converted_val = json.loads('32.45')
type(converted_val)
Run Code Online (Sandbox Code Playgroud)
产出
type <'float'>
Run Code Online (Sandbox Code Playgroud)
编辑
但是,要回答您的问题:
re.match()
从字符串的开头开始返回部分匹配。由于您不断评估每个模式匹配,因此“ 2010-00-10”的序列如下所示:
if patternTEXT.match(str_obj): #don't use 'string' as a variable name.
Run Code Online (Sandbox Code Playgroud)
它匹配,因此odp
设置为“文本”
然后,您的脚本会执行以下操作:
if patternFLOAT.match(str_obj):
Run Code Online (Sandbox Code Playgroud)
没有匹配项,odp
仍等于“文字”
if patternINT.match(str_obj):
Run Code Online (Sandbox Code Playgroud)
部分匹配odp
设置为“ INT”
由于match返回部分匹配,因此if
将评估多个语句,最后评估的语句将确定返回的字符串odp
。
您可以执行以下操作之一:
重新排列if语句的顺序,以使最后一个匹配的语句正确。
在其余的语句中使用if
和elif
,if
以便仅评估要匹配的第一个语句。
检查以确保匹配对象与整个字符串匹配:
...
match = patternINT.match(str_obj)
if match:
if match.end() == match.endpos:
#do stuff
...
Run Code Online (Sandbox Code Playgroud)