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

时间:2013-04-04 16:02:20

标签: objective-c macos command-line sed

我正在将Objective-C方法声明转换为selector,即删除类似于此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'

任何sed向导都能伸出援手吗?

4 个答案:

答案 0 :(得分:6)

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

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

这可能会做你想要的:

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

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

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

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

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

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

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

  7. s/[[:blank:]]*[;{][[:blank:]]*$//从行尾删除;{以及任何周围的空格。这对于使下一个命令正常工作非常重要。

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

  9. 示例:

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

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

答案 1 :(得分:1)

尝试使用执行此操作:

$ echo '- (void)getCString:(char *)buffer maxLength:(NSUInteger)maxLength ' |
perl -lne '/^\s*-\s*\(\w+\)\s*(\w+:)\([^\)]+\)\w+\s+(\w+:)/ && print $1, $2'
getCString:maxLength:

答案 2 :(得分:0)

这是一个sed版本,至少在样本上有效(它有点欺骗,从最后拉出maxLength):

echo "- (void)getCString:(char *)buffer maxLength:(NSUInteger)maxLength" \
| sed -ne '/[[:alnum:]]:/{;s/^[^)]*)\s*\([^:]*:\).*)\([[:alnum:]]*\)$/\1\2:/;p}'
getCString:maxLength:

这个从中间拉出maxLength:

 echo "- (void)getCString:(char *)buffer maxLength:(NSUInteger)maxLength" \
| sed -ne '/[[:alnum:]]:/{;s/^[^)]*)\s*\([^:]*:\)[^)]*\s*\S*\s*\([^:]*:\).*/\1\2/;p}'
getCString:maxLength:

答案 3 :(得分:0)

$ awk -F'[() ]' '{print $4 $8}' file
getCString:maxLength:

$ cat file
- (void)getCString:(char *)buffer maxLength:(NSUInteger)maxLength