Xcode - 用正则表达式和两位数捕获组替换函数(反向引用)

时间:2012-10-24 12:35:57

标签: objective-c regex xcode replace

我想在项目选项中使用Xcode的find来规范化方法的签名。

我写了查找表达式:

^\s*([+-])\s*\((\w+)\s*(\*?)\s*\)\s*(\w+)(\s*(:)\s*(\()\s*(\w+)\s*(\*?)\s*(\))\s*(\w+))?

和替换表达式:

\1 \(\2\3\)\4\6\7\8\9\10\11

测试字符串是:

 +(NSString *) testFunction : (NSInteger ) arg1

和期望的结果:

+ (NSString*)testFunction:(NSInteger)arg1

不幸的是,Xcode无法识别两位数的捕获组\ 10并将其转换为\ 1和'0'字符并且这么长。如何解决这个问题或bug?

提前致谢,

米哈尔

1 个答案:

答案 0 :(得分:0)

我相信@trojanfoe是正确的;正则表达式只能有九个捕获组。但是, waaay 比您的特定示例所需要的更多。

^\s*([+-])\s*\((\w+)\s*(\*?)\s*\)\s*(\w+)(\s*(:)\s*(\()\s*(\w+)\s*(\*?)\s*(\))\s*(\w+))?

\1 \(\2\3\)\4\6\7\8\9\10\11

我注意到的第一件事是你没有使用\5,所以没有理由去捕捉它。接下来,我注意到\6对应正则表达式(:),因此您可以避免捕获它并在输出中将\6替换为:\7对应(\(),因此您可以在输出中将\7替换为(。 ...迭代这种方法会产生一个更简单的正则表达式:一个用于零参数方法,一个用于一个参数方法。

^\s*([+-])\s*\((\w+)\s*(\*?)\s*\)\s*(\w+)
\1 \(\2\3\)\4

^([+-] \(\w+\*?\)\w+)\s*:\s*\(\s*(\w+)\s*(\*?)\s*\)\s*(\w+)
\1:\(\2\3\)\4

请注意,我可以捕获整个正则表达式[+-] \(\w+\*?\)\w+而没有所有那些嘈杂的\s*,因为它已经被第一个正则表达式的传递标准化了。

然而,这整个想法是一个巨大的错误。请考虑以下Objective-C方法声明:

-(const char *)toString;
-(id)initWithA: (A) a andB: (B) b andC: (C) c;
-(NSObject **)pointerptr;
-(void)performBlock: (void (^)(void)) block;
-(id)stringWithFormat: (const char *) fmt, ...;

这些都不会被正则表达式正确解析。第一个包含双字类型const char而不是单个字;第二个有多个参数;第三个有双指针;第四个有一个非常复杂的类型,而不是一个单词;第五个不仅有const char,还有一个可变参数列表。我可以继续,通过out参数和数组以及__attribute__语法,但你肯定会开始明白为什么正则表达式与此问题不匹配。

你真正想要的是一个缩进程序(以GNU indent命名,遗憾的是它没有做Objective-C)。最着名和最受支持的Objective-C缩进程序称为uncrustify;得到它here