Regex 当某些术语之间可能没有空格时,如何将一行文本中的项目分开?
在MATLAB中,我有一个文本块需要拆分。这是此类文本的一个示例:Regex 当某些术语之间可能没有空格时,如何将一行文本中的项目分开?,regex,string,matlab,scientific-notation,Regex,String,Matlab,Scientific Notation,在MATLAB中,我有一个文本块需要拆分。这是此类文本的一个示例: ROW SHORT-NAME TYPE y1 y2 yRef eq_lhs eq_rhs eq_ref errorCon tolerance isConverged 1 CmpFan.S_Qhx.integ_TmatI +6.3631e+002 +0.
ROW SHORT-NAME TYPE y1 y2 yRef eq_lhs eq_rhs eq_ref errorCon tolerance isConverged
1 CmpFan.S_Qhx.integ_TmatI +6.3631e+002 +0.0000e+000 +6.3631e+002 TgasPath Tmat TgasPath +1.0000e+000 +1.0000e-004 FALSE DY1I1
2 CmpL.S_Qhx.integ_Tmat I +8.0865e+002 +0.0000e+000 +8.0865e+002 TgasPath Tmat TgasPath +1.0000e+000 +1.0000e-004 FALSE DY2I1
3 CmpH.S_Qhx.integ_Tmat I +1.2874e+003 +0.0000e+000 +1.2874e+003 TgasPath Tmat TgasPath +1.0000e+000 +1.0000e-004 FALSE DY3I1
4 BrnPri.S_Qhx.integ_TmatI +2.8494e+003 +0.0000e+000 +2.8494e+003 TgasPath Tmat TgasPath +1.0000e+000 +1.0000e-004 FALSE DY4I1
5 TrbH.S_Qhx.integ_Tmat I +3.3983e+003 +0.0000e+000 +3.3983e+003 TgasPath Tmat TgasPath +1.0000e+000 +1.0000e-004 FALSE DY5I1
6 TrbL.S_Qhx.integ_Tmat I +2.6320e+003 +0.0000e+000 +2.6320e+003 TgasPath Tmat TgasPath +1.0000e+000 +1.0000e-004 FALSE DY6I1
7 BrnAug.S_Qhx.integ_TmatI +1.6385e+003 +0.0000e+000 +1.6385e+003 TgasPath Tmat TgasPath +1.0000e+000 +1.0000e-004 FALSE DY7I1
8 dep_FanCustomerBleed D +0.0000e+000 +0.0000e+000 +1.0000e-001 CmpFan.CbldAPTMS.WbldFanBleed 0.1 +0.0000e+000 +1.0000e-002 TRUE DY8I1
9 dep_LPCCustomerBleed D +0.0000e+000 +0.0000e+000 +1.0000e-001 CmpL.CbldAPTMS.WbldLPCbleed 0.1 +0.0000e+000 +1.0000e-002 TRUE DY9I1
10 dep_HPCCustomerBleed D +3.0000e+000 +3.0000e+000 +1.0000e-001 CmpH.CbldAPTMS.WbldHPCbleed 0.1 +0.0000e+000 +1.0000e-002 TRUE DY10I1
11 dep_HPCCustomerBleedMidD +0.0000e+000 +0.0000e+000 +1.0000e-001 CmpH.CbldAPTMSmid.WbldHPCmidBleed 0.1 +0.0000e+000 +1.0000e-002 TRUE DY11I1
12 dep_HPXhigh D +2.0000e+002 +2.0000e+002 +2.0000e+002 ShH.HPX HPXhigh HPXhigh +0.0000e+000 +1.0000e-004 TRUE DY12I1
13 dep_HPXlow D +5.0000e+002 +5.0000e+002 +5.0000e+002 ShL.HPX HPXlow HPXlow +0.0000e+000 +1.0000e-004 TRUE DY13I1
14 FlowControl.dep_Tt D +8.6941e+002 +9.2300e+002 +9.2300e+002 Fl_I.Tt Fl_O.Tt FlowControl.Fl_O.Tt-5.8056e-002 +1.0000e-004 FALSE DY14I1
15 FlowControl.dep_Pt D +7.0096e+001 +8.5000e+001 +8.5000e+001 Fl_I.Pt Fl_O.Pt FlowControl.Fl_O.Pt-1.7534e-001 +1.0000e-004 FALSE DY15I1
16 FlowControl.dep_W D +8.0000e-002 +5.4000e-001 +5.4000e-001 Fl_I.W Fl_O.W FlowControl.Fl_O.W-8.5185e-001 +1.0000e-004 FALSE DY16I1
17 MoveCCA.dep_Tt D +1.7141e+003 +1.7310e+003 +1.7310e+003 Fl_I.Tt Fl_O.Tt MoveCCA.Fl_O.Tt-9.7494e-003 +1.0000e-004 FALSE DY17I1
18 MoveCCA.dep_Pt D +7.0096e+002 +6.9900e+002 +6.9900e+002 Fl_I.Pt Fl_O.Pt MoveCCA.Fl_O.Pt+2.8001e-003 +1.0000e-004 FALSE DY18I1
19 MoveCCA.dep_W D +3.4000e+001 +2.2000e+001 +2.2000e+001 Fl_I.W Fl_O.W MoveCCA.Fl_O.W +5.4545e-001 +1.0000e-004 FALSE DY19I1
20 dep_CCAflow D +3.4000e+001 +3.4000e+001 +3.4000e+001 CmpH.B_CCA.WbldCCAflow CCAflow +0.0000e+000 +1.0000e-004 TRUE DY20I1
21 ShH.integrate_Nmech I -2.6321e+003 +0.0000e+000 +2.4194e+004 trqNet 0.0000 trqIn -1.0879e-001 +1.0000e-004 FALSE DY21I1
22 ShL.integrate_Nmech I -5.1547e+003 +0.0000e+000 +3.0562e+004 trqNet 0.0000 trqIn -1.6866e-001 +1.0000e-004 FALSE DY22I1
23 DESIGN_OPR D +5.0176e+001 +5.0000e+001 +5.0000e+001 Overall_PR D_OPR 50.0 +3.5200e-003 +1.0000e-004 FALSE DY23I1
24 DESIGN_T41 D +3.7465e+003 +3.5500e+003 +3.8000e+003 TrbH.Fl_I.Tt D_T41 3800.0 +5.1708e-002 +1.0000e-004 FALSE DY24I1
25 DESIGN_CombinedFanPR D +5.1200e+000 +4.9000e+000 +5.0000e+001 CmpFan.PR*CmpL.PRD_FANPR 50.0 +4.4000e-003 +1.0000e-004 FALSE DY25I1
26 DESIGN_ThirdStreamFlowD +9.9099e-002 +9.2500e-002 +1.3000e-001 ThirdStreamFlowD_ThirdStreamFlow0.13 +5.0762e-002 +1.0000e-004 FALSE DY26I1
27 DESIGN_RMIX D +8.2279e-001 +1.0500e+000 +1.0500e+000 Mixer.RMIX D_RMIX 1.05 -2.1639e-001 +1.0000e-004 FALSE DY27I1
28 DESIGN_Wc D +4.2158e+002 +4.2500e+002 +4.0000e+002 CmpFan.Fl_I.Wc D_WAC 400.0 -8.5534e-003 +1.0000e-004 FALSE DY28I1
每行中都有相同类型的信息,但不幸的是,按照生成方式,术语之间不一定有空格。发生这种情况时,很难/不可能知道在哪里拆分条款。如果中间的字符串信息列丢失了,我就可以了,但我仍然需要能够以某种方式获取这些数字。
对于像13这样的行,它们之间的间隔很好,下面这样的方法可以很好地工作(其中一行存储在变量“txt”中):
对于像第11行这样的行,由于第一个字符串和字符一起运行,所以根本不起作用,因此丢弃了格式字符串。类似地,它也无法知道“CmpH.cbldaptmmid.wblhdhpcmidbleed”片段应该分解为“CmpH.cbldaptmmid.Wbld”和“HPCmidBleed”。如果以后还有办法获得编号的项目和会聚标志,我可以丢失eq_lhs、eq_rhs和eq_ref信息,但这正是我努力的方向
我可以像这样抓住第一根绳子(我确实需要保留):
asCells = textscan(txt,'%d %s',1);
>> depTxt = asCells{2}{1}
depTxt =
'dep_HPCCustomerBleedMidD'
>> asCells=regexp(txt,'[+-]\d+\.?\d*([eE][+-]?\d+)?','match','forceCellOutput');
>> y1 = str2double(asCells{1}{1})
y1 =
0
>> y2 = str2double(asCells{1}{2})
y2 =
0
>> yRef = str2double(asCells{1}{3})
yRef =
0.1
>> err = str2double(asCells{1}{4})
err =
0
>> tol = str2double(asCells{1}{5})
tol =
0.01
但我不知道如何根据最后一个字符是否进入类型列来有条件地去除它
我注意到所有的实际数字都有一个前导的加号或减号,并且都是科学记数法(在本例中,eq_ref列中的数字实际上是字符串)。因此,我尝试使用regexp获取如下数值:
asCells = textscan(txt,'%d %s',1);
>> depTxt = asCells{2}{1}
depTxt =
'dep_HPCCustomerBleedMidD'
>> asCells=regexp(txt,'[+-]\d+\.?\d*([eE][+-]?\d+)?','match','forceCellOutput');
>> y1 = str2double(asCells{1}{1})
y1 =
0
>> y2 = str2double(asCells{1}{2})
y2 =
0
>> yRef = str2double(asCells{1}{3})
yRef =
0.1
>> err = str2double(asCells{1}{4})
err =
0
>> tol = str2double(asCells{1}{5})
tol =
0.01
这似乎还可以,但我不知道如何将其与前面的抓取字符串结合起来(特别是需要有条件地去掉I或D类型的字符)。我也不知道如何得到收敛标志,当它不一致时,它将在基于间距的行中的哪个项。我可以用正则表达式在每行上搜索字符串TRUE或FALSE吗?我想我已经很接近了,但是我正在努力把所有的部分放在一起。这里有一个解决方案,除了
eq\u lhs
、eq\u rhs
和eq\u ref
之外,它能让你获得一切。我不得不对正则表达式进行两次遍历,因为我无法在第一次遍历时从前瞻表达式中捕获TYPE
(可能是这样,但我不太知道如何…)
%从txt文件加载数据
fptr=fopen('myData.txt');
s=fread(fptr,inf,'uint8=>char');
fclose(fptr);
s=s';
%带命名标记的表达式
exprVarType='(I | D)(?=\s++[+-]);
exprLineStart='(?\d+)\s+(?[^\s]+(?=(\s*I |\s*d |)(\s+(I | d |'))+[^+-]+;
exprSciNot1='(?[+\-]?(?:0[1-9]\d*)(?:\.\d*)?(?:[eE][+\-]?\d+));
exprSciNot2='(?[+\-]?(?:0[1-9]\d*)(?:\.\d*)?(?:[eE][+\-]?\d+));
exprSciNot3='(?[+\-]?(?:0[1-9]\d*)(?:\.\d*)?(?:[eE][+\-]?\d+));
exprSciNot4='(?[+\-]?(?:0[1-9]\d*)(?:\.\d*)?(?:[eE][+\-]?\d+));
exprSciNot5='(?[+\-]?(?:0 |[1-9]\d*)(?:\.\d*)?(?:[eE][+\-]?\d+));
%连接正则表达式
myExpr=strcat(exprlinest,exprSciNot1,'\s+',exprSciNot2,。。。
“\s+”,exprSciNot3,[^+-]+”,exprSciNot4,“\s+”,exprSciNot5,“\s+”,。。。
“(\w+”、“\s+”、“([^\r\n]+)”;
%第一步:收集除
% 3. 类型
% 7. 均衡器
% 8. 均衡器rhs
% 9. 等式参考
myData=regexp(s,myExpr,'names');
%第二步:收集变量类型
%无法在第一次通过时捕获此信息,因为这是前瞻的一部分
%表情
varType=regexp(s,exprVarType,'match');
%将varType分配给myData结构
[myData.varType]=deal(varType{:});
您不能用另一种语言编辑此文本吗?在尝试使用您的代码时,我意识到另一种有效类型是C(我认为这是唯一的另一种)。只需快速更改exprVarType和exprLineStart即可实现此目的。然后,我还添加了几行代码,将数字转换为结构中的数字字段,而不是字符数组字段。非常感谢。我现在又遇到了新的困难。在同一类型文件中的不同文本块中,代码没有正确处理这一行:<代码> DePixMixel-TooSultDe+1.0738 e+003 +1.0738 e++ 003 +1.0738 e+ 003混合器。FlsiII1.Affy+Mixel.FlsiI2.ActhMixel.AlaMixEdDpPixDe++0.00 e++1+100000 E-0.4真Dy31 I1 < /Cl>这是因为EqllHS表达式中间的加号。对于这种情况如何进行调整,有什么建议吗?我认为它必须像在加号之后检测一个非数字字符(可能还有空格)。我认为问题在于表达式[^+-]++
,我会考虑在中间的3列中还有什么占位符,并尽快与您联系!