Using regexp to parse plot's LineSpec

7 ビュー (過去 30 日間)
Modal Analyst
Modal Analyst 2022 年 9 月 23 日
コメント済み: Walter Roberson 2022 年 10 月 7 日
Hello, I'm trying to parse the LineSpec string used in plot(...,LineSpec).
LineSpec specifies the plot line's style/marker/color, for example "-or". Some of the possible options are:
  • Style: - | -- | .- | -. | :
  • Marker: [o+*._|sd^v><]
  • Color: [rgbcymkw]
So far I had some success in regexp with
regexp(str,'((-[-|.]?)|:|(.-))?+[o+*._|sd^v><]?+[rgbcymkw]?','match','once')
and
regexp(str,'^(?:([rgbcymkw.:-*sodv^><][^.]*)(?!.*\1))+$','match','once')
or by splitting and erasing the string at each stage (not an elegant solution). However, this method parses also words, is not strict against repetitions and fails by changing the order.
I am trying to split a LineSpec into its three components, but just having regexp recognize a string as a valid LineSpec would be great. Would it possible to do this with a regexp pattern?
Thank you in advance.

採用された回答

Walter Roberson
Walter Roberson 2022 年 9 月 24 日
編集済み: Walter Roberson 2022 年 9 月 24 日
Shapes and colors in linespec may be given in full or in any leading prefix of the word, and the parts can be run together with no delimiter. For example 'greens' is green colour and square marker, and 'diacy' is cyan diamond.
There is overlap between the color codes and the names of the shapes, so you have to contend with 'square' versus 'squared' vs 'squarer'. The rule appears to be that a valid name is consumed as long as possible, and parsing picks up again from there. So 'squarer' parses out 'square' and leaves it positioned for parsing 'r' for red, but 'squared' does not "back up" to split as "squa" and "red". 'square' + 'd' is invalid because square and d (diamond) are both shapes. 'squareg' and 'redsqua' would be fine though as would be 'res'.
Thus you cannot just search for color codes and you cannot just enumerate all of the possible prefixes for shapes and colors in the same list and use a {0,2} construct to permit 0, 1 or 2 of them in a row. You have to enumerate all of the non-conflicting combinations of prefixes.
You might need to diagram out a transition table like a DFA (deterministic finite automata) and convert it to a long regular expression with lots of "or"
  3 件のコメント
Benjamin Deuell
Benjamin Deuell 2022 年 10 月 7 日
Model Analyst, do you have an example of your solution using plot.m to parse LineSpec? in particular I'm wondering if there is a clean way to do this without disrupting other plots I am working with.
Walter Roberson
Walter Roberson 2022 年 10 月 7 日
if you have h = plot(....) then
% cell array. Each entry will be an rgb triple row vector or else 'none'
linecolors = {h.Color}
% cell array of character vectors possibly including 'none'.
markershapes = {h.Marker};
% cell array. Each entry will be an rgb triple row vector or else 'none' or
% 'auto'. typically 'auto'
markeredgecolors = {h.MarkerEdgeColor};
% cell array. Each entry will be an rgb triple row vector or else 'none' or
% 'auto'. Typically 'none'
markerfacecolors = {h.MarkerFaceColor};

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

その他の回答 (0 件)

カテゴリ

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

Community Treasure Hunt

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

Start Hunting!

Translated by