在python中,如何将文本格式与没有正则表达式的字符串匹配?
我正在阅读一份文件,其中的表格行举例如下:在python中,如何将文本格式与没有正则表达式的字符串匹配?,python,regex,matlab,readfile,Python,Regex,Matlab,Readfile,我正在阅读一份文件,其中的表格行举例如下: [ 0 ] L= 9 (D) R= 14 (D) p= 0.0347222 e= 10 n= 34 我看了看由 [I,L,Ls,R,Rs,p,e,n] = textread(f1,'[ %u ] L= %u%s R= %u%s p= %n e=%u n=%u') 我想用Python读取这个文件。我所知道的唯一一件事就是正则表达式,即使阅读这行的一部分也会得出类似的结论 re.compile('\s*\[\s*(?P<id>\d+)\s*
[ 0 ] L= 9 (D) R= 14 (D) p= 0.0347222 e= 10 n= 34
我看了看由
[I,L,Ls,R,Rs,p,e,n] = textread(f1,'[ %u ] L= %u%s R= %u%s p= %n e=%u n=%u')
我想用Python读取这个文件。我所知道的唯一一件事就是正则表达式,即使阅读这行的一部分也会得出类似的结论
re.compile('\s*\[\s*(?P<id>\d+)\s*\]\s*L\s*=\s*(?P<Lint>\d+)\s*\((?P<Ltype>[DG])\)\s*R\s*=\s*(?P<Rint>\d+)\s*')
重新编译('\s*\[\s*(?P\d+)\s*\]\s*L\s*=\s*(?P\d+)\s*\(?P[DG])\)\s*R\s*=\s*(?P\d+)\s*)
太难看了!在Python中有没有更简单的方法来实现这一点?Python没有scanf等价物 Python当前没有与scanf()等效的版本。正则表达式通常比scanf()格式的字符串更强大,但也更详细。下表提供了scanf()格式标记和正则表达式之间或多或少的等效映射
但是,您可能可以使用该页面上的映射来构建自己的scanf类模块。您可以使用escape/replace来构建regexp,从而使其更具可读性
number = "([-+0-9.DdEe ]+)"
unit = r"\(([^)]+)\)"
t = "[X] L=XU R=XU p=X e=X n=X"
m = re.compile(re.escape(t).replace("X", number).replace("U", unit))
在我看来,这有点像蟒蛇:
line = "[ 0 ] L= 9 (D) R= 14 (D) p= 0.0347222 e= 10 n= 34"
parts = (None, int, None,
None, int, str,
None, int, str,
None, float,
None, int,
None, int)
[I,L,Ls,R,Rs,p,e,n] = [f(x) for f, x in zip(parts, line.split()) if f is not None]
print [I,L,Ls,R,Rs,p,e,n]
Pyparsing是不可读且脆弱的正则表达式处理器的一种回退。下面的解析器示例处理您声明的格式,加上各种额外的空格和任意顺序的赋值表达式。正如您在正则表达式中使用命名组一样,pyparsing支持结果名称,因此您可以使用dict或属性语法(data['Lint']或data.Lint)访问解析后的数据
此外,解析操作在解析时进行字符串->整型或字符串->浮点转换,以便之后的值已经是可用的形式。(pyparsing的思想是,在解析这些表达式时,您知道由数字或
word(nums)组成的单词)
-将安全地转换为int,那么为什么不立即进行转换,而不是仅仅获取匹配字符串并重新处理字符串序列,尝试检测哪些字符串是整数、浮点等?)试试这个:实际上,正则表达式唯一不好的地方是它不是以详细模式编写的(有很多评论)。通过每行一个命名的捕获组来扩展它,它将成为一个漂亮的(准确、高效、可维护且功能齐全的)问题是正则表达式肯定会对某些输入做一些不必要的事情,特别是当有奇怪的字符,并且没有明确的标准时。我只是想要一些我知道可以工作的东西。%u
应该被\d+
代替,而不是([-+0-9.DdEe]+)
和%s
可以替换为\s+
请参见
from pyparsing import Suppress, Word, nums, oneOf, Regex, ZeroOrMore, Optional
# define basic punctuation
EQ,LPAR,RPAR,LBRACK,RBRACK = map(Suppress,"=()[]")
# numeric values
integer = Word(nums).setParseAction(lambda t : int(t[0]))
real = Regex(r"[+-]?\d+\.\d*").setParseAction(lambda t : float(t[0]))
# id and assignment fields
idRef = LBRACK + integer("id") + RBRACK
typesep = LPAR + oneOf("D G") + RPAR
lExpr = 'L' + EQ + integer("Lint")
rExpr = 'R' + EQ + integer("Rint")
pExpr = 'p' + EQ + real("pFloat")
eExpr = 'e' + EQ + integer("Eint")
nExpr = 'n' + EQ + integer("Nint")
# accept assignments in any order, with or without leading (D) or (G)
assignment = lExpr | rExpr | pExpr | eExpr | nExpr
line = idRef + lExpr + ZeroOrMore(Optional(typesep) + assignment)
# test the parser
text = "[ 0 ] L= 9 (D) R= 14 (D) p= 0.0347222 e= 10 n= 34"
data = line.parseString(text)
print data.dump()
# prints
# [0, 'L', 9, 'D', 'R', 14, 'D', 'p', 0.034722200000000002, 'e', 10, 'n', 34]
# - Eint: 10
# - Lint: 9
# - Nint: 34
# - Rint: 14
# - id: 0
# - pFloat: 0.0347222