3

我正在将 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

4 回答 4

6

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

您可以使用非标准-E标志告诉 sed 使用 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. /^[-+]/-选择以 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:

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

于 2013-04-04T20:57:55.147 回答
1

执行此操作:

$ echo '- (void)getCString:(char *)buffer maxLength:(NSUInteger)maxLength ' |
perl -lne '/^\s*-\s*\(\w+\)\s*(\w+:)\([^\)]+\)\w+\s+(\w+:)/ && print $1, $2'
getCString:maxLength:
于 2013-04-04T18:51:28.763 回答
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:
于 2013-04-04T19:44:23.583 回答
0
$ awk -F'[() ]' '{print $4 $8}' file
getCString:maxLength:

$ cat file
- (void)getCString:(char *)buffer maxLength:(NSUInteger)maxLength
于 2013-04-04T21:19:34.090 回答