尝试使用NSMutableArray对NSString进行排序



我有一个NSString,它保存的信息是这样的:

%hook APMIntro
- (bool)isIntroductoryOffer {
return NO;
}
%end
%hook APMIntro
- (void)setIntroductoryOffer:(bool)arg1 {
arg1 = NO;
%orig;
}
%end
%hook ChallengeProgressHolder
- (void)setHasItem:(bool)arg1 {
arg1 = NO;
%orig;
}
%end
%hook ChallengeProgressHolder
- (bool)hasItem {
return NO;
}
%end

我想要达到的最终结果是这个

%hook APMIntro
- (bool)isIntroductoryOffer {
return NO;
}
- (void)setIntroductoryOffer:(bool)arg1 {
arg1 = NO;
%orig;
}
%end
%hook ChallengeProgressHolder
- (void)setHasItem:(bool)arg1 {
arg1 = NO;
%orig;
}
- (bool)hasItem {
return NO;
}
%end
到目前为止,我已经尝试使用NSMutableArray来分离不同的行来尝试和组织它们-但结果是一个无限循环。到目前为止,我已经尝试了这个代码
-(NSString *)cleanUp:(NSString *)cleanUp{
NSMutableArray *content = [[cleanUp componentsSeparatedByString:@"%hook "] mutableCopy];
//  NSMutableArray *content = [[NSMutableArray alloc] init];
NSMutableArray *cleaned = [[NSMutableArray alloc] init];
NSMutableArray *hooks = [[NSMutableArray alloc] init];
//      NSArray *messy = [[cleanUp componentsSeparatedByString:@"n"] mutableCopy];
cleanUp = @"";
NSString *line, *line1;
//NSString *fixMe = @"";
for (unsigned h = 1; h < content.count; h++){
line = [content objectAtIndex:h-1];
if ([line hasPrefix:@"#import"]){
[cleaned addObject:[NSString stringWithFormat:@"%@n", line]];
continue;
} else {
cleanUp = [NSString stringWithFormat:@"%@%%hook %@", cleanUp, line];
//[content addObject:[NSString stringWithFormat:@"%hook %@", line]];
}
}
//NSLog(@"nnn%@nnn", cleanUp);
BOOL lookingForEnd = NO;
BOOL hookFound = NO;
hooks = [[cleanUp componentsSeparatedByString:@"n"] mutableCopy];
//  NSString *hook;
//NSLog(@"nnn%@nnn", hooks);
for (unsigned i = 1; i < hooks.count; i++){
line = [hooks objectAtIndex:i-1];
//NSLog(@"%i: %@nn", i, line);
if (lookingForEnd) {
[cleaned addObject:[NSString stringWithFormat:@"%@n", line]];
if ([line isEqualToString:@"%end"]){
lookingForEnd = NO;
//i = 1;
continue;
} else if ([line1 isEqualToString:line]){
lookingForEnd = YES; 
}
}
if ([line hasPrefix:@"%hook"]){
line1 = line;
for (unsigned j = 1; j < hooks.count; j++){
printf("nnnHOOKnnn");
if ([[hooks objectAtIndex:j-1] isEqual:line1]){
printf("nnnFOUNDnnn");
[hooks addObject:line];
[cleaned addObject:[NSString stringWithFormat:@"%@n", line]];
lookingForEnd = YES;
hookFound = YES;
//break;
}
}
}
}
NSLog(@"%@n", cleaned);
return cleaned;
}

在设置了这个并进一步阅读了如何对数组进行排序之后——我发现这一切都错了——我只是不确定如何才能正确地进行排序。

提前感谢-任何帮助都是非常感激的

可能可以用一个复杂的RegEx来完成这一切——但是,这里有一点"一步一步"方法。

创建一个具有两个字符串属性的NSObject类——blockNameblockBody

我们将使用这个正则表达式:

(^%hook )(.*?)(?=%end$)

将字符串分割为几个部分。"%hook "one_answers"%以何种.

然后,循环遍历匹配项,创建一个包含"block"对象,每个对象都有名称和主体。

接下来,我们按blockName对数组进行排序。

最后,循环遍历已排序的数组,用"body "格式化输出字符串。分组到命名块。

那么,如果我们有:

MyBlock.h

@interface MyBlock : NSObject
@property (strong, nonatomic) NSString *blockName;
@property (strong, nonatomic) NSString *blockBody;
@end

MyBlock.m

#import "MyBlock.h"
@implementation MyBlock
@end

,我们从您的样品NSString开始:

%hook APMIntro
- (bool)isIntroductoryOffer {
return NO;
}
%end
%hook APMIntro
- (void)setIntroductoryOffer:(bool)arg1 {
arg1 = NO;
%orig;
}
%end
%hook ChallengeProgressHolder
- (void)setHasItem:(bool)arg1 {
arg1 = NO;
%orig;
}
%end
%hook ChallengeProgressHolder
- (bool)hasItem {
return NO;
}
%end

可以这样做:

NSString *input = [self sampleString];
NSMutableArray <MyBlock *> *blocks = [NSMutableArray new];
NSString *pattern = @"(^%hook )(.*?)(?=%end$)";
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:pattern options:NSRegularExpressionDotMatchesLineSeparators | NSRegularExpressionAnchorsMatchLines error:NULL];
NSArray *myArray = [regex matchesInString:input options:0 range:NSMakeRange(0, [input length])] ;
for (NSTextCheckingResult *match in myArray) {
// get the range starting after "%hook "
NSRange matchRange = [match rangeAtIndex:2];
// get the "block" string
NSString *s = [input substringWithRange:matchRange];
// split it by newLines
NSArray <NSString *> *a = [s componentsSeparatedByString:@"n"];
// we want the "body" to skip the first line
NSRange r;
r.location = 1;
r.length = [a count] - 1;
// get the lines excluding the first line
NSArray <NSString *> *a2 = [a subarrayWithRange:r];
// new MyBlock object
MyBlock *b = [MyBlock new];
b.blockName = [a firstObject];
b.blockBody = [a2 componentsJoinedByString:@"n"];
[blocks addObject:b];
}
// sort the array of blocks by blockName
NSArray <MyBlock *> *sortedArray;
sortedArray = [blocks sortedArrayUsingComparator:^NSComparisonResult(MyBlock *a, MyBlock *b) {
return [a.blockName compare:b.blockName];
}];
NSMutableString *output = [NSMutableString new];
NSString *curName = @"";
// loop through the array of blocks
for (int i = 0; i < [sortedArray count]; i++) {
MyBlock *b = sortedArray[i];
// if we're at a "new" blockName
if (![curName isEqualToString:b.blockName]) {
curName = b.blockName;
// add %end if output is not ""
if ([output length] != 0) {
[output appendString:@"%endn"];
}
// add a new line of %hook blockName
[output appendFormat:@"n%%hook %@n", curName];
}
// add the block body
[output appendFormat:@"%@", b.blockBody];
}
// "close" the last block
[output appendString:@"%endn"];
// log the resulting string
NSLog(@"%@", output);

,该示例的输出是:

%hook APMIntro
- (bool)isIntroductoryOffer {
return NO;
}
- (void)setIntroductoryOffer:(bool)arg1 {
arg1 = NO;
%orig;
}
%end
%hook ChallengeProgressHolder
- (void)setHasItem:(bool)arg1 {
arg1 = NO;
%orig;
}
- (bool)hasItem {
return NO;
}
%end

根据需要设置输出格式(换行,空格等):)

最新更新