removing parentheses around digits using regular expressions

Dear all, I am slowly making progress on my learning of regular expressions. At the moment, I am trying to solve the following problem: replace all occurrences of (n) with n, where n is a number, provided that no alphabetical letter occurs before the first parenthesis. As an example,
str='(2)+p_5*(3)-(0.3)'
would become
2+p_5*3-0.3
I wrote the following
regexprep(str,'(\W)(\()([.012345789]+)(\))','$1$3')
but it does not solves the problem if one of the expressions to change occurs at the beginning as in the example above. More concretely, the answer I get from running this is
(2)+p_5*3-0.3
which is not the expected result.
Thanks in advance for any help
Pat.

 採用された回答

Matt Fig
Matt Fig 2012 年 10 月 5 日
編集済み: Matt Fig 2012 年 10 月 5 日

1 投票

regexprep(str,'(\()([\d*\.]+)(\))','$2')

10 件のコメント

Patrick Mboma
Patrick Mboma 2012 年 10 月 5 日
Hi Matt,
Your solution does not work on this example
(2)+p_5*(3)-(0.3)+exp(3)
no change should occur if the opening parenthesis is preceded by an alphabetical letter.
Thanks,
Pat
Matt Fig
Matt Fig 2012 年 10 月 5 日
編集済み: Matt Fig 2012 年 10 月 5 日
Try this one:
regexprep(str,'(?<![\w])(\()([\d*\.]+)(\))','$2')
Walter Roberson
Walter Roberson 2012 年 10 月 5 日
nb: the (?<![\w]) is an example of look-behind.
Matt Fig
Matt Fig 2012 年 10 月 5 日
Yes, and it seems to work!
str='(2)+p_5*(3)-(0.3)+sin(0)-cos(6.7)+(3)^(2-3) + (55.55)'
regexprep(str,'(?<![\w])(\()([\d*\.]+)(\))','$2')
ans =
2+p_5*3-0.3+sin(0)-cos(6.7)+3^(2-3) + 55.55
Patrick Mboma
Patrick Mboma 2012 年 10 月 5 日
This is very helpful. Actually the (.) should occur at most once and so a fully correct expression would be
regexprep(str,'(?<![\w])(\()(\d*\.?\d*)(\))','$2')
Thanks a lot Matt.
Pat.
per isakson
per isakson 2012 年 10 月 5 日
(\d*\.?\d*) matches a single "."
Walter Roberson
Walter Roberson 2012 年 10 月 5 日
(\d*\.?\d*) also matches the empty string.
It does not, however, match infinity, or any irrational number.
per isakson
per isakson 2012 年 10 月 5 日
"matches the empty string", what does that mean with regular expressions? In what type of cases could matching an empty string cause an effect?
Walter Roberson
Walter Roberson 2012 年 10 月 5 日
For example, 1+()*2 the empty string inside the () would match because all parts of \d*\.?\d* are optional, so the expression would be converted to 1+*2
Also, I note that the problem description does not disallow numeric characters before the (), so 1+Henkel2(7)*5 would be converted to 1+Henkel27*5
per isakson
per isakson 2012 年 10 月 5 日
編集済み: per isakson 2012 年 10 月 6 日
Yes.
Assuming the requirement is to match numbers only. The second expression below seems to be closer to a working one. However, what expression is taught in the book?
>> regexprep( '(12),(.12),(12.),(1.2),(.),()' ...
, '\((\d*\.?\d*)\)', '#$1' )
ans =
#12,#.12,#12.,#1.2,#.,#
>> regexprep( '(12),(.12),(12.),(1.2),(.),()' ...
, '\(((\d+\.?\d*)|(\d*\.\d+))\)', '#$1' )
ans =
#12,#.12,#12.,#1.2,(.),()
.
\w takes care of the case with Henkel2 - by intent or not. However, are there any cases, in which "(" should be replaced when preceded by a digit?

サインインしてコメントする。

その他の回答 (2 件)

Walter Roberson
Walter Roberson 2012 年 10 月 5 日

0 投票

Consider using a "look-behind"

2 件のコメント

Patrick Mboma
Patrick Mboma 2012 年 10 月 5 日
編集済み: Patrick Mboma 2012 年 10 月 5 日
Hi Walter,
My knowledge of regular expressions is not that good yet... I don't know yet how to implement "look behinds".

サインインしてコメントする。

per isakson
per isakson 2012 年 10 月 5 日
編集済み: per isakson 2012 年 10 月 5 日

0 投票

>> regexprep( str, '\(([\d.]+)\)', '$1' )
ans =
2+p_5*3-0.3
str =
(2)+p_5*(3)-(0.3)+exp(3)
>> regexprep( str, '\(([\d.]+)\)', '$1' )
ans =
2+p_5*3-0.3+exp3
  • *\(* represents "("
  • \) represents ")"
  • [\d.]+ represents one or more digits and periods, e.g. "....0" and "2"
  • (expr) "Group regular expressions and capture tokens." The token may be refered to in the replacement string by $1 - "1" because it is the first
Every substring in the string that matches this expression is replaced, i.e. a number enclosed by parentheses is replaced by the number.
.
--- in response to a comment ---
>> regexprep( str, '(?<!\w)\(([\d.]+)\)', '$1' )
ans =
2+p_5*3-0.3+exp(3)
better
>> regexprep( str, '(?<![a-zA-Z])\(([\d.]+)\)', '$1' )
because \w includes digits.
  • (?<![a-zA-Z]) "Look behind from current position and test if expr is not found." Where expr evaluates to a letter. Thus, if preceded by a letter there is no match.

7 件のコメント

Patrick Mboma
Patrick Mboma 2012 年 10 月 5 日
Hi Per, This would not work. Here is a counter-example
'(2)+p_5*(3)-(0.3)+exp(3)'
your solution would give
'2+p_5*3-0.3+exp3'
per isakson
per isakson 2012 年 10 月 5 日
編集済み: per isakson 2012 年 10 月 5 日
Yes, it does. What should it give? OK preceded by letter
per isakson
per isakson 2012 年 10 月 5 日
What about atan2()?
Matt Fig
Matt Fig 2012 年 10 月 5 日
The solution I posted in the comments to my answer handles atan2.
str='(2)+p_5*(3)-(0.3)+cos(5.7)+(3)^(2-3) + (.55) + atan2(9)';
regexprep(str,'(?<![\w])(\()([\d*\.]+)(\))','$2')
ans =
2+p_5*3-0.3+cos(5.7)+3^(2-3) + .55 + atan2(9)
per isakson
per isakson 2012 年 10 月 5 日
編集済み: per isakson 2012 年 10 月 5 日
Yes, and that is because "\w" stands for "[A-Za-z0-9]". However, it is difficult to know whether including "0-9" might have any unintended side effects.
I find it difficult to construct robust expressions. However, I have never tried to learn regular expressions in a systematic way.
Patrick Mboma
Patrick Mboma 2012 年 10 月 5 日
I am currently doing just that, with you guys' help.
Thanks to everybody.
Pat.
per isakson
per isakson 2012 年 10 月 6 日
編集済み: per isakson 2012 年 10 月 6 日

サインインしてコメントする。

カテゴリ

ヘルプ センター および File ExchangeProgrammatic Model Editing についてさらに検索

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by