简体   繁体   English

Cocoa / Objective-C中的简单字符串解析:将命令行解析为命令和参数

[英]Simple string parsing in Cocoa / Objective-C: parsing a command line into command and arguments

Here's a piece of code to take a string (either NSString or NSAttributedString) input that represents a command line and parse it into two strings, the command cmd and the arguments args : 这是一段代码,用于获取表示命令行的字符串(NSString或NSAttributedString) input ,并将其解析为两个字符串,命令cmd和参数args

NSString* cmd = [[input mutableCopy] autorelease];
NSString* args = [[input mutableCopy] autorelease];
NSScanner* scanner = [NSScanner scannerWithString:[input string]];
[scanner scanUpToCharactersFromSet:[NSCharacterSet 
                                    whitespaceAndNewlineCharacterSet] 
                        intoString:&cmd];
if (![scanner scanUpToString:@"magicstring666" intoString:&args]) args = @"";

That seems to work but the magic string is a pretty absurd hack. 这似乎有效,但魔术字符串是一个非常荒谬的黑客。 Also, I'm not at all sure I'm doing things right with the autoreleases. 而且,我完全不确定我是否正确使用自动释放功能。

ADDED: The solution should also be robust to initial whitespace. 补充:解决方案对初始空格也应该是健壮的。 Also, I originally had the input string called both input and inStr . 另外,我最初的输入字符串同时叫做inputinStr Sorry for that confusion. 对不起,这个混乱。

ADDED: I believe one thing the above code gets right that the answers so far don't is that args should not have any initial whitespace. 补充:我相信上面的代码有一点是正确的,到目前为止答案不是args不应该有任何初始空格。

NSString *cmd;
NSScanner *scanner = [NSScanner scannerWithString:[inStr string]];
[scanner scanUpToCharactersFromSet:[NSCharacterSet
                                    whitespaceAndNewlineCharacterSet] 
                        intoString:&cmd];
NSString *args = [[scanner string] substringFromIndex:[scanner scanLocation]];

Your autoreleases were OK, but allocating strings in the first place was unnecessary since NSScanner returns a new string by reference. 您的自动释放是正常的,但首先分配字符串是不必要的,因为NSScanner通过引用返回一个新字符串。 Since NSScanner's charactersToBeSkipped include whitespace by default, it shouldn't get tripped up by initial whitespace. 由于NSScanner的charactersToBeSkipped默认包含空格,因此不应该被初始空格绊倒。

Something like this? 像这样的东西?

int index = [input rangeOfString:@" "].location;
NSString *cmd = [input substringToIndex:index]);
NSString *args = [input substringFromIndex:index + 1]);

The autoreleases you mentioned don't actually make any sense, all you're doing is creating a mutable copy (NSMutableString *) that's properly autoreleased, but since you're casting it to an NSString * there's no practical difference then just saying cmd = input; 您提到的自动释放实际上没有任何意义,您所做的只是创建一个可正确自动释放的可变副本(NSMutableString *),但是因为您将它转换为NSString *所以没有实际区别,只是说cmd = input; . Even that's not needed for args though, since NSScanner will overwrite what's there anyway. 即便如此,args也不需要,因为NSScanner会覆盖那里的东西。

The rangeOfString: would work, if you want to go this route you can trim leading whitespaces using NSString's stringByTrimmingCharactersInSet method (I would also test to be sure both arguments and the command exist, or you'll get an error). rangeOfString:可以工作,如果你想走这条路线你可以使用NSString的stringByTrimmingCharactersInSet方法修剪前导空格(我也会测试以确保两个参数和命令都存在,否则你会得到一个错误)。 What I would do though, is use the NSString componentsSeparatedByCharactersInSet: method. 我会做的是使用NSString componentsSeparatedByCharactersInSet:方法。 This will give you an NSArray object containing the command and each argument in a separate index. 这将为您提供一个NSArray对象,其中包含命令和单独索引中的每个参数。

If you want to expand the string into a full array of arguments like the input to 'main', you can use wordexp. 如果要将字符串扩展为完整的参数数组,例如“main”的输入,则可以使用wordexp。

#import <wordexp.h>

+ (NSMutableArray*) splitArgumentString:(NSString*)strArgs
{
    wordexp_t expandedArgs;
    NSMutableArray *argArray = [NSMutableArray array];

    if(strArgs != nil && 0 == wordexp([strArgs UTF8String], &expandedArgs, 0))
    {
        for(size_t i = 0; i < expandedArgs.we_wordc; ++i)
        {
            NSString arg = [NSString stringWithCString:expandedArgs.we_wordv[i] encoding:NSUTF8StringEncoding];
            [argArray addObject:arg];
        }
        wordfree(&expandedArgs);
    }
    return argArray;        
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM