sed regex从方法声明中提取选择器(Obj-C)

Jay*_*Jay 3 macos command-line sed objective-c

我正在将Objective-C方法声明转换为其选择器,即删除参数名称和类型,如此NSString方法:

- (void)getCString:(char *)buffer maxLength:(NSUInteger)maxLength

要得到

getCString:maxLength:

所以我发现正则表达式\w*?\:将提取我需要的东西(在http://gskinner.com/RegExr/等在线正则表达式检查器sed中正常工作)但我无法(在OS X上)工作用正则表达式提取签名.

从各种sed片段/样本页面我得到的印象是这样的东西应该有效,除非它没有(我尝试过的~250种差异......):

 cat test.m | sed '/\w*?\:/p'
Run Code Online (Sandbox Code Playgroud)

任何sed巫师都可以伸出援手吗?

rob*_*off 6

您正在尝试提取方法选择器,而不是方法签名.方法签名包括返回类型和参数类型.方法选择器仅包括关键字和冒号.

您可以使用非标准-E标志告诉sed使用POSIX扩展正则表达式.

这可能会做你想要的:

sed -E -n '/^[-+]/{
    s/^.[[:blank:]]*(\([^)]*\))?[[:blank:]]*//
    s/[[:blank:]]*[;{][[:blank:]]*$//
    s/:[^:]*([[:blank:]]|$)/:/g
    p
}' test.m
Run Code Online (Sandbox Code Playgroud)

这对初学者来说是一个相当复杂的sed命令,所以让我们分解它.

  1. -E标志在Mac OS X等FreeBSD衍生产品上启用扩展正则表达式.

  2. -n标志告诉sed不要自动打印每个输入行.

  3. /^[-+]/选择以a -(对于实例方法)或a +(对于类方法)开头的每一行.

  4. {开始一组sed命令,这些命令将在每个选定的行上执行.小组以匹配结束}.

  5. s/^.[[:blank:]]*(\([^)]*\))?[[:blank:]]*//删除-or +,后跟任意数量的空格,后跟方法的返回类型,后跟任意数量的空格.它通过匹配a (后跟任意数量的非)字符后跟a来删除返回类型).请注意,返回类型实际上是可选的; 声明的方法- foo:(int)x;完全有效(并且默认返回类型为id).另请注意,如果方法的返回类型是显式函数指针或块,则此正则表达式将无法正常工作- (void (^)(void))getBlock;,因为您无法使用正则表达式处理嵌套括号.

  6. s/[[:blank:]]*[;{][[:blank:]]*$//从行的末尾删除;or {和任何周围的空格.这对于使下一个命令正常工作很重要.

  7. s/:[^:]*([[:blank:]]|$)/:/g匹配冒号,后跟尽可能多的非:字符,后跟空格或行尾,并用冒号替换匹配.尾随g标志告诉sed为该行的每个匹配执行此操作.此命令删除参数类型和名称.请注意,与删除返回类型的命令不同,此命令将正确处理嵌套括号.另请注意,参数类型也是可选的; - foo:bar是一个采用一个参数(其类型默认为id)的方法.

例:

:; echo '- (void)getCString:(char *)buffer maxLength:(NSUInteger)maxLength' | sed -E -n '/^[-+]/{
    s/^.[[:blank:]]*(\([^)]*\))?[[:blank:]]*//
    s/[[:blank:]]*[;{][[:blank:]]*$//
    s/:[^:]*([[:blank:]]|$)/:/g
    p
}'
getCString:maxLength:
Run Code Online (Sandbox Code Playgroud)

请注意,此sed命令也适用于没有参数的方法,例如- (void)save;.