Форум программистов, компьютерный форум CyberForum.ru

Objective-C

Войти
Регистрация
Восстановить пароль
 
Рейтинг: Рейтинг темы: голосов - 9, средняя оценка - 4.67
alexpac26
14 / 22 / 0
Регистрация: 20.01.2013
Сообщений: 125
#1

упрощенный RegexKitLite - Objective-C

25.04.2013, 16:46. Просмотров 1043. Ответов 12
Метки нет (Все метки)

phpRegexKitLite.h
Objective-C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
// PHPregexKitLite
 
#import <Foundation/Foundation.h>
#import "RegexKitLite.h"
 
 
#ifndef phpRegexKitLite_class
#define phpRegexKitLite_class
 
static RKLRegexOptions preg_options_extract(NSMutableString* pattern);
static NSString * preg_match(NSString * pattern, NSString* subject);
static NSArray * preg_match_all(NSString * pattern, NSString* subject);
static NSArray * preg_explode(NSString * pattern, NSString* subject);
static NSArray * preg_split(NSString * pattern, NSString* subject);
static NSString * preg_replace(NSString* pattern ,NSString* replacement ,NSString* subject);
 
/*
 подключение к RegexKitLite
 
 libicucore.dylib (framework)
 -fno-objc-arc (флаг компиляции без ARC)
 
 */
 
/*
 i - чувствительность к регистру
 s - символ . означает также переносы строк
 m - многострочные выражения
 u - юникод
 c - комментарии в выражениях
 
 
 синтаксис выражений  почти полностью идентичен синтаксису php выражений
 
 примеры
 
 NSString *s = @"Hello world";
 
 bool ok = preg_match(@"#hello w#",s);
 
 ok == false
 
 bool ok = preg_match(@"#hello w#i",s); // флаг чувствительность к регистру
 
 ok == true
 
 выражение должны быть заключено между скобками  # или любым другим символом
 фгаги обработки выражения пишутся после
 
 
 RKLNoOptions             = 0,
 RKLCaseless              = 2,
 RKLComments              = 4,
 RKLDotAll                = 32,
 RKLMultiline             = 8,
 RKLUnicodeWordBoundaries = 256
 */
 
static RKLRegexOptions preg_options_extract(NSMutableString* pattern) {
    NSString *s1 = [pattern substringToIndex:1];
    for (int z=pattern.length-1; z>=1; z--) {
        if ([[pattern substringWithRange:NSMakeRange(z, 1)] isEqualToString:s1]) {
            // обнаружено
            // разбор флагов
            RKLRegexOptions ret = RKLNoOptions;
            NSString *flags = [pattern substringWithRange:NSMakeRange(z+1, pattern.length-z-1)];
            for (int i=0; i<flags.length; i++) {
                NSString *f = [flags substringWithRange:NSMakeRange(i, 1)];
                if ([f isEqualToString:@"i"]) {
                    ret = (ret | RKLCaseless);
                    continue;
                }
                if ([f isEqualToString:@"s"]) {
                    ret = (ret | RKLDotAll);
                    continue;
                }
                if ([f isEqualToString:@"m"]) {
                    ret = (ret | RKLMultiline);
                    continue;
                }
                if ([f isEqualToString:@"u"]) {
                    ret = (ret | RKLUnicodeWordBoundaries);
                    continue;
                }
                if ([f isEqualToString:@"c"]) {
                    ret = (ret | RKLComments);
                    continue;
                }
            }
            // сохраняем выражение
            
            [pattern setString:[pattern substringWithRange:NSMakeRange(1, z-1)]];
            NSLog(@"parrent is %@", pattern);
            return ret;
        }
    }
    NSLog(@"RegExPreg::preg_options_extract : invalid pattern detected %@",pattern);
    return RKLNoOptions;
}
 
 
static NSString * preg_match(NSString * pattern, NSString* subject) {
    NSMutableString *sp = [NSMutableString stringWithString:pattern];
    RKLRegexOptions opt = preg_options_extract(sp);
    return  [subject stringByMatching:sp options:opt inRange:NSMakeRange(0, subject.length) capture:0 error:NULL];
}
 
static NSArray * preg_match_all(NSString * pattern, NSString* subject) {
    NSMutableString *sp = [NSMutableString stringWithString:pattern];
    RKLRegexOptions opt = preg_options_extract(sp);
    return  [subject arrayOfCaptureComponentsMatchedByRegex:sp options:opt range:NSMakeRange(0, subject.length) error:NULL];
}
 
static NSArray * preg_explode(NSString * pattern, NSString* subject) {
    NSMutableString *sp = [NSMutableString stringWithString:pattern];
    RKLRegexOptions opt = preg_options_extract(sp);
    return  [subject componentsSeparatedByRegex:sp options:opt range:NSMakeRange(0, subject.length) error:NULL];
}
 
static NSArray * preg_split(NSString * pattern, NSString* subject) {
    return preg_explode(pattern,subject);
}
 
static NSString * preg_replace(NSString* pattern ,NSString* replacement ,NSString* subject) {
    NSMutableString *sp = [NSMutableString stringWithString:pattern];
    RKLRegexOptions opt = preg_options_extract(sp);
    return [subject stringByReplacingOccurrencesOfRegex:sp withString:replacement options:opt range:NSMakeRange(0, subject.length) error:NULL];
}
 
#endif
список фукнций для работы


Objective-C
1
NSString * preg_match(NSString * pattern, NSString* subject);
// проверяет соотвествие выражения строке
если nil то не соотвествует

Objective-C
1
NSArray * preg_match_all(NSString * pattern, NSString* subject);
помещает в многомерный массив все совпадения выражения pattern в строке subject

Objective-C
1
2
NSArray * preg_explode(NSString * pattern, NSString* subject); 
NSArray * preg_split(NSString * pattern, NSString* subject);
возвращает массив из строки subject разделенный выражением pattern

Objective-C
1
NSString * preg_replace(NSString* pattern ,NSString* replacement ,NSString* subject);
возвращает строку в которой все совпадения pattern заменены на replacement

работа функций похожа на работу php функций что упрощает работу с функциями регулярных выражений

пример работы

Objective-C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
- (IBAction)b1:(id)sender {
 
    // показать текущий текст
    
    NSLog(@"текущий текст \n%@",_text);
 
}
 
- (IBAction)b2:(id)sender {
    // preg_match_all
    
    NSArray *matches = preg_match_all(@"#co(\\w{2})(\\w+)#i", _text);
     NSLog(@"preg_match_all совпадения \n%@",matches);
    
}
 
- (IBAction)b3:(id)sender {
    // preg_replace
    NSString* s = preg_replace(@"#(\\w)\\w+#", @"$1zzz", _text);
    NSLog(@"preg_replace текст \n%@",s);
    
}
 
- (IBAction)b4:(id)sender {
    NSArray *matches = preg_split(@"#flag#i", _text);
     NSLog(@"preg_split массив \n%@",matches);
}
для выражений используется следующий синтаксис

#выражение#флаги

если всеже надо использовать сивол # то допускается любой другой в качестве скобок

@выражение@флаги

общий систаксис соотвествует RegExKitLite который в свою очередь почти соотвествует php регулярным выражениям

список флагов

i - чувствительность к регистру
s - символ . означает также переносы строк
m - многострочные выражения
u - юникод
c - комментарии в выражениях

пример выражения

NSString *s = @"Hello world";

preg_match(@"#hello w#",s); // вернет НЕТ

preg_match(@"#hello w#i",s); // вернет ДА

тестовый проект во вложении
Вложения
Тип файла: zip test_regex.zip (129.5 Кб, 6 просмотров)
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
mobidevelop
182 / 182 / 3
Регистрация: 10.01.2013
Сообщений: 596
25.04.2013, 22:35     упрощенный RegexKitLite #2
А чем от встроенного отличается? Интересно просто.
alexpac26
14 / 22 / 0
Регистрация: 20.01.2013
Сообщений: 125
26.04.2013, 10:54  [ТС]     упрощенный RegexKitLite #3
А чем от встроенного отличается
встроенного это какого?

nspredicate или что?
mobidevelop
182 / 182 / 3
Регистрация: 10.01.2013
Сообщений: 596
26.04.2013, 11:04     упрощенный RegexKitLite #4
– rangeOfString:options:
– rangeOfString:options:range:
– rangeOfString:options:range:locale:

а среди этих самых options есть NSRegularExpressionSearch
alexpac26
14 / 22 / 0
Регистрация: 20.01.2013
Сообщений: 125
26.04.2013, 11:13  [ТС]     упрощенный RegexKitLite #5
если там так все радужно и хорошо, то почему написали RegExKitLite ?
mobidevelop
182 / 182 / 3
Регистрация: 10.01.2013
Сообщений: 596
26.04.2013, 11:14     упрощенный RegexKitLite #6
Собственно, об этом я и спрашиваю )))
alexpac26
14 / 22 / 0
Регистрация: 20.01.2013
Сообщений: 125
26.04.2013, 11:21  [ТС]     упрощенный RegexKitLite #7
http://stackoverflow.com/questions/8...ing-comparison

один из примеров

если надо будет найти массив или распарсить чтото типа

<a.+?class="hello">(.+?)</a>думаю код в несколько раз усложниться
mobidevelop
182 / 182 / 3
Регистрация: 10.01.2013
Сообщений: 596
26.04.2013, 11:43     упрощенный RegexKitLite #8
Идея нарисовать методы для циклической обработки строк хороша. Действительно часто надо найти все вхождения выражения и приходится писать циклы. Но интерфейсы
А за идею спасибо.
Vorona
Peace 2 all shining faces
666 / 528 / 44
Регистрация: 05.03.2010
Сообщений: 1,271
26.04.2013, 22:56     упрощенный RegexKitLite #9
Цитата Сообщение от alexpac26 Посмотреть сообщение
встроенного это какого?
http://developer.apple.com/library/i...09708-CH1-SW48
такого например

в данном случае отдам предпочтение нативным методам работы с регулярными выражениями, нежели какому-то неясному phpRegexKitLite, который свалится в самом неподходящем месте или окажется, что в нем чего-то нет в самый ответственный момент, как это часто бывает с самодельными пятиколесными велосипедами
при чем тут вообще приставка php?? на objective-c вроде пишем..

Не по теме:

да и что за нотация методов preg_match_all, в objective-c camelCase вроде принято использовать, и не лоу-левел С тут, или программисты после php никак не могу без мамки обойтись?

Есть же общепринятые конвенции, которые упрощают чтение и понимание кода в разы, потом же кому-то прийдется этот код поддерживать..
то блин какие-то Array, Dict и т.д., теперь php/ruby нотации preg_match_all, preg_explode - тупо мусор какой-то
не в обиду конечно, вы меня простите за такую реакцию, но это блин плевок в лицо коллегам, которым после вас прийдется перестраиватся на это

в php было бы странно увидеть что-то вроде NSMyClassBlaBla, там я буду ожидать что-то вроде hello_world_again, в C# например у интерфейса буду ожидать приставку I - IEnumerable, так же и тут хочется видеть общепринятые условия, чтобы не отвлекать внимание на такую ерунду, а сосридоточиться на предназначении кода и вообще не заморачиваться на том, что там происходит, а просто читать названия методов как привычный английский, но это уже другая тема

mobidevelop
182 / 182 / 3
Регистрация: 10.01.2013
Сообщений: 596
27.04.2013, 00:05     упрощенный RegexKitLite #10
Цитата Сообщение от Vorona Посмотреть сообщение
http://developer.apple.com/library/i...09708-CH1-SW48
такого например
О! Ссыль правильная! Все теги в одном месте. Спасибо!

Добавлено через 9 минут
И все переборы в этом классе тоже реализованы. Эх, век живи, век учись, дураком помрешь... Опять мне анализ странички в моем проекте переписывать :-)
alexpac26
14 / 22 / 0
Регистрация: 20.01.2013
Сообщений: 125
27.04.2013, 11:11  [ТС]     упрощенный RegexKitLite #11
Цитата Сообщение от Vorona Посмотреть сообщение
http://developer.apple.com/library/i...09708-CH1-SW48
такого например

в данном случае отдам предпочтение нативным методам работы с регулярными выражениями, нежели какому-то неясному phpRegexKitLite, который свалится в самом неподходящем месте или окажется, что в нем чего-то нет в самый ответственный момент, как это часто бывает с самодельными пятиколесными велосипедами
при чем тут вообще приставка php?? на objective-c вроде пишем..
интерпретация стандартных методов

SimpleRegex.h
Objective-C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
#import <Foundation/Foundation.h>
 
/*
 
 
 NSRegularExpressionCaseInsensitive             i
 NSRegularExpressionAllowCommentsAndWhitespace  c
 NSRegularExpressionIgnoreMetacharacters        m
 NSRegularExpressionDotMatchesLineSeparators    s
 NSRegularExpressionAnchorsMatchLines           l
 NSRegularExpressionUseUnixLineSeparators       x
 NSRegularExpressionUseUnicodeWordBoundaries    u
 
 // [url]http://developer.apple.com/library/ios/#documentation/Foundation/Reference/NSRegularExpression_Class/Reference/Reference.html#//apple_ref/doc/uid/TP40009708-CH1-SW48[/url]
 
 
 */
 
 
#ifndef SimpleRegex_class
#define SimpleRegex_class
 
static NSRegularExpressionOptions p_option_extract(NSMutableString* pattern);
static NSString * p_match(NSString * pattern, NSString* subject);
static NSMutableArray * p_match_all(NSString * pattern, NSString* subject);
static NSString * p_replace(NSString* pattern ,NSString* replacement ,NSString* subject);
 
 
 
static NSRegularExpressionOptions p_option_extract(NSMutableString* pattern) {
    NSString *s1 = [pattern substringToIndex:1];
    if ([s1 isEqualToString:@"#"]) {
        // обнаружены флаги
        for (int z=pattern.length-1; z>=1; z--) {
            if ([[pattern substringWithRange:NSMakeRange(z, 1)] isEqualToString:s1]) {
                // обнаружено
                // разбор флагов
                NSRegularExpressionOptions ret = 0;
                NSString *flags = [pattern substringWithRange:NSMakeRange(z+1, pattern.length-z-1)];
                for (int i=0; i<flags.length; i++) {
                    NSString *f = [flags substringWithRange:NSMakeRange(i, 1)];
                    if ([f isEqualToString:@"i"]) {
                        ret = (ret | NSRegularExpressionCaseInsensitive);
                        continue;
                    }
                    if ([f isEqualToString:@"s"]) {
                        ret = (ret | NSRegularExpressionDotMatchesLineSeparators);
                        continue;
                    }
                    if ([f isEqualToString:@"l"]) {
                        ret = (ret | NSRegularExpressionAnchorsMatchLines);
                        continue;
                    }
                    if ([f isEqualToString:@"u"]) {
                        ret = (ret | NSRegularExpressionUseUnicodeWordBoundaries);
                        continue;
                    }
                    if ([f isEqualToString:@"x"]) {
                        ret = (ret | NSRegularExpressionUseUnixLineSeparators);
                        continue;
                    }
                    if ([f isEqualToString:@"c"]) {
                        ret = (ret | NSRegularExpressionAllowCommentsAndWhitespace);
                        continue;
                    }
                    if ([f isEqualToString:@"m"]) {
                        ret = (ret | NSRegularExpressionIgnoreMetacharacters);
                        continue;
                    }
                }
                // сохраняем выражение
                [pattern setString:[pattern substringWithRange:NSMakeRange(1, z-1)]];
                return ret;
            } // end if
        } // end for
    } // end if
    return 0;
}
 
static NSString * p_match(NSString * pattern, NSString* subject) {
    NSMutableString *pattern_ok = [NSMutableString stringWithString:pattern];
    NSRegularExpressionOptions opt = p_option_extract(pattern_ok);
 
    NSRegularExpression *reg = [NSRegularExpression regularExpressionWithPattern:pattern_ok options:opt error:NULL];
    NSTextCheckingResult *res = [reg firstMatchInString:subject options:NSMatchingReportProgress range:NSMakeRange(0, subject.length)];
    
    if (res.range.length==0) {
        return nil;
    } else {
        return [subject substringWithRange:res.range];
    }
    
}
 
//- (void)enumerateMatchesInString:(NSString *)string options:(NSMatchingOptions)options range:(NSRange)range usingBlock:(void (^)(NSTextCheckingResult *result, NSMatchingFlags flags, BOOL *stop))
 
 
 
static NSMutableArray * p_match_all(NSString * pattern, NSString* subject) {
    NSMutableString *pattern_ok = [NSMutableString stringWithString:pattern];
    NSRegularExpressionOptions opt = p_option_extract(pattern_ok);
    
    NSRegularExpression *reg = [NSRegularExpression regularExpressionWithPattern:pattern_ok options:opt error:NULL];
    NSArray *res = [reg matchesInString:subject options:NSMatchingReportProgress range:NSMakeRange(0, subject.length)];
                    //NSMatchingReportProgress range:NSMakeRange(0, subject.length)];
    NSMutableArray *res2 = [NSMutableArray new];
    
    for (id obj in res) {
        [res2 addObject: [subject substringWithRange:[obj range]]]; 
    }
    
    return res2;
}
 
static NSString * p_replace(NSString* pattern ,NSString* replacement ,NSString* subject) {
    NSMutableString *pattern_ok = [NSMutableString stringWithString:pattern];
    NSRegularExpressionOptions opt = p_option_extract(pattern_ok);
    
    NSRegularExpression *reg = [NSRegularExpression regularExpressionWithPattern:pattern_ok options:opt error:NULL];
 
    return [reg stringByReplacingMatchesInString:subject options:NSMatchingReportProgress range:NSMakeRange(0, subject.length) withTemplate:replacement];
}
 
#endif
и сразу подводные камни

1) – matchesInString:options:range:
возвращает не двухмерный массив в случае если надо найти подвыражения, а одномерный

<a>(.+?)</a>

=> потеря в функционале

2) аналога preg_split там нету

в остальном вроде вполне нормально (:
Вложения
Тип файла: zip test_regex.zip (193.0 Кб, 6 просмотров)
mobidevelop
182 / 182 / 3
Регистрация: 10.01.2013
Сообщений: 596
27.04.2013, 11:54     упрощенный RegexKitLite #12
Поправьте меня кто-нибудь, кто лучше меня знает регулярные выражения, но мне кажется, что выражение "<a>(.+?)</a>" должно выдать не несколько строк, а все содержимое между первым вхождением "<a>" и последним "</a>". Т.е. там вообще одна строка должна быть. Для регулярок вообще пункт 1 замечания корректен?
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
27.04.2013, 14:45     упрощенный RegexKitLite
Еще ссылки по теме:

C# Упрощенный доступ к элементам класса
DirectDraw -> сообщение windows 7 упрощенный стиль Delphi
Разработать упрощенный сервер HTTP протокола Python
Упрощенный сниффер 802.11 C++
Windows 7 После разгона процессора включается упрощенный стиль

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
alexpac26
14 / 22 / 0
Регистрация: 20.01.2013
Сообщений: 125
27.04.2013, 14:45  [ТС]     упрощенный RegexKitLite #13
в данном случае отдам предпочтение нативным методам работы с регулярными выражениями, нежели какому-то неясному phpRegexKitLite, который свалится в самом неподходящем месте или окажется
чтобы он не валился да и вообще не давал повода в себе усомниться, необходимо и достаточно написать грамотную документацию и сделать что-то типа официальной страницы в интернете

ну и конечно опробовать его в реальном проекте, то есть протестировать на практике

и после этого, внезапно, все не так уже плохо ))
Yandex
Объявления
27.04.2013, 14:45     упрощенный RegexKitLite
Ответ Создать тему
Опции темы

Текущее время: 12:48. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru