How do I match nested parenthesis (brackets, or braces) with dynamic regular expressions?

49 ビュー (過去 30 日間)
One can read all over the web how it is impossible to use regular expressions to match nexted parenthesis. However MATLAB has this cool feature called 'dynamic regular expressions' that allow one to insert some MATLAB code to do all kinds of special 'gymnastics'. Is there a way to use this feature to count instances of parenthesis and, in turn, find their matches? Consider the following string:
g = 'asdf (( dwer e: ( asdedsdskek))::)asd fg ( qwe 4 dfy5 57) q34 dqa5';
or
g = 'asdf (( (dwer ) e: ( asdedsdskek))::)asd fg ( qwe 4 dfy5 57) q34 dqa5';
or
g = 'asdf ( dwer e: )asd fg ( qwe 4 dfy5 57) q34 dqa5';
Specifically, my need is only to match the first left parenthesis with its partner but one would think the more general solution of matching all sets of parenthesis is feasible with dynamic regular expressions. If anyone can help with this, it would be much appreciated.

採用された回答

Stephen23
Stephen23 2020 年 4 月 1 日
編集済み: Stephen23 2020 年 4 月 1 日
This matches the outer-most matched pair of parentheses:
>> str = 'asdf (( dwer e: ( asdedsdskek))::)asd fg ( qwe 4 dfy5 57) q34 dqa5';
>> fun = @(s)sprintf('.{%d}',find(cumsum((s==')' )-(s=='('))>0,1,'first'));
>> out = regexp(str,'\((??@fun($''))','match')
out =
'(( dwer e: ( asdedsdskek))::)' '( qwe 4 dfy5 57)'
  2 件のコメント
Dan
Dan 2020 年 4 月 1 日
Wow ... spending your covid-19 quarentine perusing old MATLAB questions? I appreciate the effort.
Andreas Bernatzky
Andreas Bernatzky 2020 年 4 月 6 日
hahah thanks Stephen, I needed that too :)

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

その他の回答 (2 件)

Walter Roberson
Walter Roberson 2014 年 3 月 17 日
It might be possible, but it will not be easy.
The regular expressions supported by MATLAB are very similar to the regular expressions supported by Perl.
Here is one way to use Perl just to count to see if parens are matched:
In pattern matching in Perl in which you are trying to balance pairs, see
and the (?PARNO) construct described at
The (?PARNO) and recurse constructs are not supported by MATLAB.
You just might be able to use the dynamic expressions to invoke a function that names itself inside of a dynamic expression, thus achieving recursion.
Warning: you will spend a lot of time getting it right. It would be much easier to write some code that did the analysis then to try to use regular expressions for it.
  1 件のコメント
Dan
Dan 2014 年 3 月 18 日
Thanks, Walter ... I ended up pulling in the string and writing a little MATLAB subroutine to do the task so I'm not motivated to research your references. Hopefully someone else can use the information in the future. Dan

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


Daniel Renjewski
Daniel Renjewski 2023 年 3 月 15 日
編集済み: Daniel Renjewski 2023 年 3 月 15 日
I have got a similar problem as I wanted to identify fractions in the string of an equation to replace it with proper latex code. The following function gives you the position of all pairs of open and closing brackets with their respective position in the string, assuming there are indeed only pairs.
str = 'asdf (( dwer e: ( asdedsdskek))::)asd fg ( qwe 4 dfy5 57) q34 dqa5'
str = 'asdf (( dwer e: ( asdedsdskek))::)asd fg ( qwe 4 dfy5 57) q34 dqa5'
br = detect_brackets(str)
br = 4×2
17 30 7 31 6 34 42 57
for idx = 1:size(br,1)
display(str(br(idx,1):br(idx,2)))
end
( asdedsdskek) ( dwer e: ( asdedsdskek)) (( dwer e: ( asdedsdskek))::) ( qwe 4 dfy5 57)
function [oc] = detect_brackets(str)
oc = [];
% find all opening and closing brackets in the string
op=strfind(str,'(');
cl=strfind(str,')');
% search for pairs until all are identified
while ~isempty(op | cl)
% find opening bracket for first closing bracket
idx = find(op < cl(1),1,'last');
% append this pair to function output
oc = [oc;op(idx) cl(1)];
% remove found opening bracket from vector
op(idx) = [];
% remove found closing bracket from vector
cl(1) = [];
end
end

カテゴリ

Help Center および File ExchangeWhos についてさらに検索

製品

Community Treasure Hunt

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

Start Hunting!

Translated by