필터 지우기
필터 지우기

How to access data of regexp output (without temporary variable)?

조회 수: 16 (최근 30일)
Simon
Simon 2023년 4월 26일
댓글: Stephen23 2023년 5월 13일
I know how to convert the output from regexp( ) to a table by intermediating through a temporary variable as this solution:
strT = ["apple 001"; "banana 102"; "orange 344 001"];
C = regexp(strT, '\s', 'split', 'once'); % temporary variable
array2table(vertcat(C{:,:})) % desired output, except I hope there's a way to avoid braces.
ans = 3×2 table
Var1 Var2 ________ _________ "apple" "001" "banana" "102" "orange" "344 001"
I wonder if there is a way to cascade/pipeline function calls in a single line. It seems that similar questions had been asked zillion times (this post said so.) But I want to learn more about Matlab, so forgive me for asking it again.
% I tried this, but it doesn't give the desired result.
cell2table(regexp(strT, '\s', 'split', 'once'))
ans = 3×1 table
Var1 _____________________ "apple" "001" "banana" "102" "orange" "344 001"

채택된 답변

Stephen23
Stephen23 2023년 4월 26일
편집: Stephen23 2023년 4월 26일
The general answer to the question has not changed much since 2012.
Using a temporary variable is not "less efficient" as many beginners might imagine (most likely MATLAB will generate the intermediate cell array internally anyway).
str = ["apple 001"; "banana 102"; "orange 344 001"];
tbl = splitvars(cell2table(regexp(str, '\s', 'split', 'once')))
tbl = 3×2 table
Var1_1 Var1_2 ________ _________ "apple" "001" "banana" "102" "orange" "344 001"
Note that this creates and discards an intermediate table, so uses more memory.
Personally I would recommend using the intermediate variable: while code golf is very entertaining, it does not serve the purpose of clarity and efficiency. In one year you will come back to this code any wonder what it does, how it works, and what side-effects it has. Code is read more times than it is written, so clarity when reading is valuable.
On top of that, hiding intermediate arrays within nested function call makes debugging harder.
  댓글 수: 1
Simon
Simon 2023년 4월 26일
There are several advices for good coding habit in your answer. Thanks again. (I gradually realize that a couple fantacies I learned from Python coding turn out not quite ok, oneliner functions being one.)

댓글을 달려면 로그인하십시오.

추가 답변 (3개)

albara
albara 2023년 4월 26일
편집: per isakson 2023년 4월 26일
You can access the data of the regexp output directly without using a temporary variable by using the syntax [~,~,~,match] = regexp(str, expr), where str is the input string and expr is the regular expression you want to match.
The regexp function returns multiple outputs, including the start and end indices of the match, any tokens captured by the regular expression, and the matched substring. By using the ~ symbol as a placeholder for the outputs you don't need, you can ignore them and only keep the matched substring.
Here is an example:
% Define input string and regular expression
str = 'The quick brown fox jumps over the lazy dog';
expr = 'brown';
% Use regexp to find the matching substring and access it directly
[~, ~, ~, match] = regexp(str, expr);
% Display the matching substring
disp(match)
In this example, regexp is used to find the first occurrence of the word "brown" in the input string str. The ~ symbol is used as a placeholder for the outputs we don't need, and the match variable is used to store the matching substring directly.
The output of this code will be the string 'brown'. Note that you can access any of the other outputs of regexp by using the corresponding placeholder variables, such as [start, end, tokens, match] = regexp(str, expr) to store the start and end indices and any tokens in separate variables.
  댓글 수: 3
Simon
Simon 2023년 5월 13일
Your codes didn't return the same result in my Matlab version (2023a). The result your codes return is the same as the one below. I just checked out array2table( ) manual page. Its behavior has not changed. Why we have different results from the same codes?
strT = ["apple 001"; "banana 102"; "orange 344 001"];
array2table(cell2mat(cellfun(@(x) str2double(x), regexp(strT, '\s', 'split', 'once'), 'UniformOutput', false)))
ans = 3×2 table
Var1 Var2 ____ ____ NaN 1 NaN 102 NaN NaN
array2table(regexp(strT, '(\S+)\s+(\S+)', 'tokens', 'once'))
ans = 3×1 table
Var1 _____________________ {["apple" "001" ]} {["banana" "102"]} {["orange" "344"]}
Stephen23
Stephen23 2023년 5월 13일
"Why we have different results from the same codes?"
Within a regular expression the meta-character \S only matches non-whitespace characters:
"orange" "344 001"
% ^ so there is no way it could return this

댓글을 달려면 로그인하십시오.


Rik
Rik 2023년 4월 26일
If you insist on a single line, you can even use subsref to index the result of regexp. That will make your code hard to read and hard to modify.
Why don't you write a wrapper function you can call regexp2table like this:
strT = ["apple 001"; "banana 102"; "orange 344 001"];
regexp2table(strT, '\s', 'split', 'once') % Look, ma, one line
ans = 3×2 table
Var1 Var2 ________ _________ "apple" "001" "banana" "102" "orange" "344 001"
function tab=regexp2table(varargin)
% All inputs are piped to regexp().
C = regexp(varargin{:});
tab = array2table(vertcat(C{:}));
end
  댓글 수: 1
Simon
Simon 2023년 5월 13일
Thanks. Your code and the idea behind it might come handy for solving more difficult regexp problems.

댓글을 달려면 로그인하십시오.


Dyuman Joshi
Dyuman Joshi 2023년 4월 26일
Experimenting lead to this -
str = ["apple 001"; "banana 102 3579"; "orange 344 001"]
str = 3×1 string array
"apple 001" "banana 102 3579" "orange 344 001"
C = array2table([extractBefore(str,' ') extractAfter(str,' ')])
C = 3×2 table
Var1 Var2 ________ __________ "apple" "001" "banana" "102 3579" "orange" "344 001"
  댓글 수: 1
Simon
Simon 2023년 5월 13일
I was not aware of extractBefore( ) or extractAfter( ). Very nice solution. Thanks!

댓글을 달려면 로그인하십시오.

카테고리

Help CenterFile Exchange에서 Data Type Conversion에 대해 자세히 알아보기

제품


릴리스

R2023a

Community Treasure Hunt

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

Start Hunting!

Translated by