找回密码
 注册
Simdroid-非首页
查看: 125|回复: 6

关于条件判断 正则表达

[复制链接]
发表于 2013-7-4 10:43:50 | 显示全部楼层 |阅读模式 来自 山东青岛
最近看了高手的关于正则表达的讨论,想提出一个实用的问题:
str={'w10n10e' 'w10s10w' 'w0n170.5w'}
其中最前的'w'是风速的意思,可以忽略;后边的'n' 'e' 's' 'w'表示北纬 东经 南纬 西经。
如何转化得到下面结果:
location=[[10 10] [-10 350] [0 189.5]

点评

好问题  发表于 2013-7-4 10:45

评分

1

查看全部评分

 楼主| 发表于 2013-7-4 11:34:35 | 显示全部楼层 来自 山东青岛
Simdroid开发平台
补充:下面是我的代码,比较耐心的一种解法
str='w10s20w'
str=str(2:end)
ensw=str(str>'a')
if ensw(1)=='n'
    lat = str2double(str(2:(strfind(str,ensw(1))-1)))
else
    lat = str2double(str(2:(strfind(str,ensw(1))-1)))*(-1)
end
if ensw(2)=='e'
    lon = str2double(str((strfind(str,ensw(1))+1):(strfind(str,ensw(2))-1)))
else
    lon = 360-str2double(str((strfind(str,ensw(1))+1):(strfind(str,ensw(2))-1)))
end
回复 不支持

使用道具 举报

发表于 2013-7-4 11:41:05 | 显示全部楼层 来自 北京
本帖最后由 liuyalong008 于 2013-7-4 23:11 编辑

先贴一个:
  1. str={'w10n10e' 'w10s10w' 'w0n170.5w'}
  2. s=regexprep(regexprep(str,'^\w',''),'([\d\.]+)(\w)([\d\.]+)(\w)','$2$1$4$3')
  3. % 去掉开始的w,并把数字和后面的符号互换
  4. t=regexp(regexprep(s,{'n|e','s|w'},{'+','-'}),'.[\d\.]+','match')
  5. % 把n和e用+号代替,把sw用-号代替,并提取数字
  6. p=reshape(cellfun(@str2num,[t{:}]),[],numel(str))'
  7. p(p(:,2)<0,2)=p(p(:,2)<0,2) +360
  8. % 经度转化
  9. p =

  10.                         10                        10
  11.                         10                        350
  12.                          0                         189.5
复制代码
要编辑一个帖子很容易出错,编辑模式巨烂无比

评分

1

查看全部评分

回复 不支持

使用道具 举报

发表于 2013-7-4 13:56:54 | 显示全部楼层 来自 英国
本帖最后由 nwcwww 于 2013-7-4 13:59 编辑

确实是个好问题,感谢楼主。
  1. loc = cellfun(@str2num, regexprep(str, '\w(\d+\.*\d*)([ns])(\d+\.*\d*)([we])',...
  2.     '${char(strcmpi($2, ''s'')*45)}$1 ${num2str(str2num([num2str(($4==119)*360) char(($4==119)*45+($4~=119)*43) $3]))}'), 'uni', 0);
复制代码
分步解释:
  1. '\w(\d+\.*\d*)([ns])(\d+\.*\d*)([we])';
  2. %匹配,不单用\d+是考虑到小数点。当然也可以用[^a-z];

  3. ${char(strcmpi($2, ''s'')*45)}$1;
  4. %如果$2是字母's', 输出-$1,否则是正的$1;

  5. num2str(($4==119)*360);
  6. %如果$4是字母'w',输出字符串'360',否则是'0'。当然这里也可以用strcmp;

  7. char(($4==119)*45+($4~=119)*43);
  8. %如果$4是'w', 输出'-', 否则是'+';

  9. ${num2str(...)};
  10. %因此有两种情况,如果$4是'w', 则计算360-$4并转成字符串,否则则是0+$4;

  11. %剩下的cellfun和regexprep就不用解释了
复制代码
或者代码这么写也行
  1. loc = cellfun(@str2num, regexprep(str, {'\w([^a-z]+)([ns])([^a-z]+)e', '\w([^a-z]+)([ns])([^a-z]+)w'},...
  2. {'${char(strcmpi($2, ''s'')*45)}$1 $3', '${char(strcmpi($2, ''s'')*45)}$1 ${num2str(360-str2double($3))}'}), 'uni', 0);
复制代码
大同小异,这里用的是regexprep(str, {cond1, cond2}, {do1, do2})的语法来处理最后应该是360-x还是x。

评分

2

查看全部评分

回复 不支持

使用道具 举报

发表于 2013-7-4 21:17:48 | 显示全部楼层 来自 英国
  1. str={'w10n10e' 'w10s10w' 'w0n170.5w'};

  2. % 4种组合,一个个替换。
  3. pattern1 = '\w(\d+\.*\d*)n(\d+\.*\d*)e';
  4. pattern2 = '\w(\d+\.*\d*)n(\d+\.*\d*)w';
  5. pattern3 = '\w(\d+\.*\d*)s(\d+\.*\d*)e';
  6. pattern4 = '\w(\d+\.*\d*)s(\d+\.*\d*)w';

  7. loc1 = regexprep(str, pattern1,'[$1,$2]');
  8. loc2 = regexprep(loc1,pattern2,'[$1,360-$2]');
  9. loc3 = regexprep(loc2,pattern3,'[-$1,$2]');
  10. loc4 = regexprep(loc3,pattern4,'[-$1,360-$2]'); % 已替换完毕。
  11. % loc4 = '[10,10]'    '[-10,360-10]'    '[0,360-170.5]'

  12. loc5 = cell2mat([cellfun(@(x) eval(x),loc4,'uniform',false)]');% 化成矩阵的形式
复制代码

评分

2

查看全部评分

回复 不支持

使用道具 举报

发表于 2013-7-5 20:46:22 | 显示全部楼层 来自 英国
regexprep()函数是否存在Bug?
Tokens in Replacement Strings
When using tokens in a replacement string, reference them using $1, $2, etc. instead of \1, \2, etc.

下面各例中regexprep(...)中的'$1'对应的Token是 '(\d+)',它应该是指连续的数字,
但是下面几例中 \d+ 代表的不仅仅是数字,还包含了字母。
怎么解释呢?

str={'w10n10e', 'w10s10w', 'w0n170.5w'};

regexprep(str,'(\d+)','$1') % 仅保留token 1,即 (\d+) 所指的数字。
% ans =
%     'w10n10e'    'w10s10w'    'w0n170.5w'

regexprep(str,'(\d+).*?(\d+)','$1')
% ans =
%     'w10e'    'w10w'    'w0.5w'

regexprep(str,'(\d+).*?(\d+)','$1,$2')
% ans =
%     'w10,10e'    'w10,10w'    'w0,170.5w'

regexprep(str,'w(\d+).*?(\d+)','$1,$2')
% ans =
%     '10,10e'    '10,10w'    '0,170.5w'

regexp()函数不存在此现象。
regexp(str,'(\d+)','tokens'); celldisp(ans)
regexp(str,'(\d+).*?(\d+)','tokens'); celldisp(ans)
regexp(str,'(\d+).*?(\d+)','tokens'); celldisp(ans)
regexp(str,'w(\d+).*?(\d+)','tokens'); celldisp(ans)
输出均为数字,正常。

评分

1

查看全部评分

回复 不支持

使用道具 举报

发表于 2013-7-8 09:44:18 | 显示全部楼层 来自 河北廊坊
lin2009 发表于 2013-7-5 20:46
regexprep()函数是否存在Bug?
Tokens in Replacement Strings
When using tokens in a replacement string ...

疏本人愚钝,没有看出bug

str={'w10n10e', 'w10s10w', 'w0n170.5w'};
regexprep(str,'(\d+)','$1')
这句话的意思是字符串中连续的数字,替换为第一个()中的内容,不匹配的内容,不做变化
第一个w,不是连续数字,故保留下来,10被替换为10,n保留,10被替换我10,e保留下来,因此
% ans =
%     'w10n10e'    'w10s10w'    'w0n170.5w'

regexprep(str,'(\d+).*?(\d+)','$1')
w保留,10n10满足条件,被替换为10,e保留下来,因此
% ans =
%     'w10e'    'w10w'    'w0.5w'

regexp和regexprep的区别在于

前者是找到满足条件的子串,后者是将其中的满足条件的子串替换,不满足条件的保留的

以上仅是本人理解,不对之处,望指正

点评

谢谢!浅显易懂的解释。  发表于 2013-7-8 16:22

评分

1

查看全部评分

回复 不支持

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

Archiver|小黑屋|联系我们|仿真互动网 ( 京ICP备15048925号-7 )

GMT+8, 2024-6-21 00:34 , Processed in 0.067814 second(s), 20 queries , Gzip On, MemCache On.

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表