[英]Efficient way to insert characters between other characters in a string
在MATLAB中用一个符号替换/插入一个符号(符号系列)的几种有效方法与被替换的符号相对应的是什么?
例如,考虑具有字符串Eq
: Eq = 'A*exp(-((x-xc)/w)^2)'
。 有没有办法来取代*
同.*
, /
用./
, \\
与.\\
,并^
与.^
不用写四个独立strrep()
线?
正则表达式可以很好地完成工作。 正则表达式只是在文本中找到模式。 您可以通过正则表达式指定要查找的模式类型,输出将为您提供模式发生位置的位置。
对于我们的特定情况,我们不仅想要找到模式发生的位置,我们还希望用其他东西替换这些模式。 具体来说,使用MATLAB中的函数regexprep
将字符串中的匹配替换为其他内容。 你想要做的是通过添加一个替换所有*
, /
, \\
和^
符号.
在每个人面前。
regexprep
工作原理是第一个输入是你正在查看的字符串,第二个输入是你试图找到的模式。 在我们的例子中,我们想要找到*
, /
, \\
和^
任何一个。 要指定此模式,请将这些所需符号放在[]
括号中。 正则表达式保留\\
作为特殊符号来描述可以被解析为正则表达式但实际上不是正则表达式的字符。 因此,您需要将\\\\
用于\\
字符,将\\^
用于^
字符。 第三个输入是您想要替换每个匹配的内容。 在我们的例子中,我们只想重用每个匹配的字符,但我们添加了一个.
在比赛开始时。 这是通过在正则表达式语法中执行\\.$0
来完成的。 $0
表示获取匹配产生的第一个令牌......这实际上是模式中匹配的符号。 .
也是使用正则表达式的保留关键字,因此我们必须在前面添加一个\\
符号。
无需再费周折:
>> Eq = 'A*exp(-((x-xc)/w)^2)';
>> out = regexprep(Eq, '[*/\\\^]', '\.$0')
out =
A.*exp(-((x-xc)./w).^2)
我们正在寻找的模式是[*/\\\\\\^]
,这意味着我们想要找到任何*
, /
, \\
- 在regex中表示为\\\\
,并且\\^
- 在正则表达式中表示为^
。 我们想要找到这些符号中的任何一个,并通过添加一个符号来替换它们.
前面的角色 - \\.$0
。
作为一个更复杂的例子,让我们确保在示例方程中包含您要查找的所有符号:
>> A = 'A*exp(-((x-xc)/w)^2) \ b^2';
>> out = regexprep(A, '[*/\\\^]', '\.$0')
out =
A.*exp(-((x-xc)./w).^2) .\ b.^2
我会像雷格里恩的回答那样使用正则regexp
。 但这是另一种方法,只是为了提供替代方案。
ops = '*/\^'; %// operators that need a dot
ii = find(ismember(Eq, ops)); %// find where dots should be inserted
[~, jj] = sort([1:numel(Eq) ii-.5]); %// will be used to properly order the result
result = [Eq repmat('.',1,numel(ii))]; %// insert dots at the end
result = result(jj); %// properly order the result
一个变种:
ops = '*/\^'; %// operators that need a dot
ii = find(ismember(Eq, ops)); %// find where dots should be inserted
jj = sort([1:numel(Eq) ii-.5]); %// dot locations are marked with fractional part
result = Eq(ceil(jj)); %// repeat characters where the dots will be placed
result(mod(jj,1)>0) = '.'; %// place dots at indices with fractional part
vectorize
函数几乎已经完成了你想要的所有功能,除了它不会将mldivide
( \\
)转换为ldivide
( .\\
)。
通过“高效”,你的意思是更少的代码行还是更快? 正则表达式几乎总是比其他方法慢,而且可读性较差。 在这种情况下,我不认为它们是必要的或者是一个好的选择。 如果你只需要将你的字符串转换一次,那么速度就不是可读性了( strrep
仍然会更快)。 如果你需要多次这样做,你提到的这个简单的代码比你的例子中的短字符串的regexrep
快4-5倍(对于更长的字符串来说要快得多):
out = strrep(Eq,'*','.*');
out = strrep(out,'/','./');
out = strrep(out,'\','.\');
out = strrep(out,'^','.^');
如果您想要一行,请使用:
out = strrep(strrep(strrep(strrep(Eq,'*','.*'),'/','./'),'\','.\'),'^','.^');
这也会稍快一些。 或者创建自己的vectorize
版本并调用它。
正则表达式闪耀在更复杂的情况下,例如,如果您的字符串已经部分向量化: Eq = 'A.*exp(-((x-xc)/w)^2)'
。 即使如此, vectorize
函数只使用strrep
,然后调用strfind
“删除任何可能的'..*'
, '../'
等。” 并使用适当的元素操作符替换它们,因为它更快(例如,符号数学字符串可能变得非常大)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.