如何在MATLAB中验证formatSpec字符串?

Dev*_*-iL 6 regex string validation matlab printf

许多在MATLAB(以及其他语言,有一个C衍生的功能scanf/ printf)用于写入或读取字符串(仅举几例:sscanf,sprintf,textscan)依靠用户提供有效的formatSpec,它告诉函数的结构字符串string-to-build或string-to-parse.我正在寻找一种方法来验证这样一个formatSpec字符串,然后在调用中sprintf使用它.

在这种情况下sprintf,文档中formatSpec描述的结构如下:

MATLAB的sprintf formatSpec

具体来说,我想指出两个方面formatSpec:

  • (✓)格式化运算符以百分号开头%,以转换字符结束.
  • (x)formatSpec还可以在百分号之前%,或在转换字符之后包含其他文本.

我正在考虑的解决方案涉及使用正则表达式来测试传入的字符串.到目前为止我所拥有的是一个似乎能够匹配初始字符%转换字符之间的所有内容的表达式,而不是可能出现的"附加文本".

(%{1}(\d+\$)?[-+\s0#]*(\d+|\*)?(\.\d+)?[bt]?[diuoxXfeEgGcs]+)+
Run Code Online (Sandbox Code Playgroud)

我想也增加了拍摄的能力."任何可打印文本字符之外%,'并且\,除非这些字符恰好出现两次".这需要%转换字符之前和之后捕获.

  • 任何可打印的字符:[ -~]
  • 此外%,'\:(?![\\%'])
  • 这些字符恰好出现两次 : ( §§§§ |'{2}|\\{2}|%{2})(§=占位符)

我遇到了" 除非 " 的问题,即获得负面预测以丢弃单次出现但允许指定字符的双重出现.

我有两个问题:

  1. 有没有更好的方法来验证formatSpec字符串(即没有正则表达式,还是使用更好的字符串)?
  2. 如何修复我的正则表达式,使其按照描述的方式工作?

消歧说明:如果formatSpec字符串在格式化运算符的两边都有"自由文本" ,则该文本应被视为下一个 格式化运算符的一部分,除非没有剩余.下面是一个formatSpec字符串应该如何split使用正则表达式的示例(其中|是每个匹配的第一个字符):

Color %s, number1 %d, number2 %05d, hex %#x, float %5.2f, unsigned value %u.
|       |           |             |        |            |                   |
Run Code Online (Sandbox Code Playgroud)

Ro *_* Mi 1

描述

((?:[ -$&(-[\]-~]|([%'\\])\2)*(%(\d+\$)?[-+\s0#]?(\d+|\*)?(\.\d+)?[bt]?[diuoxXfeEgGcs]+)+(?:(?!(?:[ -$&(-[\]-~]|([%'\\])\7)*(?:%(?:\d+\$)?[-+\s0#]?(?:\d+|\*)?(?:\.\d+)?[bt]?[diuoxXfeEgGcs]+)+)(?:[ -$&(-[\]-~]|([%'\\])\8)*)?)
Run Code Online (Sandbox Code Playgroud)

正则表达式可视化

** 要更好地查看图像,只需右键单击图像并选择在新窗口中查看

该正则表达式将执行以下操作:

  • (?:[ -$&(-[\]-~]|([%'\\])\2)*将匹配从空格到 的所有可打印字符~,除了%, \'除非它们恰好出现两次
  • (%(\d+\$)?[-+\s0#]?(\d+|\*)?(\.\d+)?[bt]?[diuoxXfeEgGcs]+)+ 是你的表情
  • (?:启动非捕获组
    • (?!(?:[ -$&(-[\]-~]|([%'\\])\7)*(?:%(?:\d+\$)?[-+\s0#]?(?:\d+|\*)?(?:\.\d+)?[bt]?[diuoxXfeEgGcs]+)+)向前查看是否有更多格式字符串
    • (?:[ -$&(-[\]-~]|([%'\\])\8)*)?如果上面没有更多格式字符串,那么这将捕获剩余的可打印字符
    • )捕获组结束

例子

现场演示

https://regex101.com/r/sV4eX3/2

示例文本

Color %s, we are looking for %%02droids %% number1 %d, number2 %05d, hex %#x, float %5.2f, unsigned value %u.
Run Code Online (Sandbox Code Playgroud)

比赛样本

MATCH 1
1.  [0-8]   `Color %s`
3.  [6-8]   `%s`

MATCH 2
1.  [8-53]  `, we are looking for %%02droids %% number1 %d`
2.  [40-41] `%`
3.  [51-53] `%d`

MATCH 3
1.  [53-67] `, number2 %05d`
3.  [63-67] `%05d`
5.  [65-66] `5`

MATCH 4
1.  [67-76] `, hex %#x`
3.  [73-76] `%#x`

MATCH 5
1.  [76-89] `, float %5.2f`
3.  [84-89] `%5.2f`
5.  [85-86] `5`
6.  [86-88] `.2`

MATCH 6
1.  [89-109]    `, unsigned value %u.`
3.  [106-108]   `%u`
Run Code Online (Sandbox Code Playgroud)