Найти числовой рисунок в строке
Я хочу, чтобы найти подстроку внутри sting, но у нее есть отличительный шаблон, я не уверен, как найти.
EX.
NSString *test1= @"Contact Names
67-444-322
Dec 21 2012
23941 6745 9145072 01567
5511 23345 614567 123456
Older Contacts
See Back Side";
Я хочу найти следующий шаблон в подстроке (эти числа, но не числа)
23941 6745 9145072 01567
5511 23345 614567 123456
Однако формат строки примера вряд ли будет прежним. Каждый раз будут разные номера и разные названия, кроме "Контактные имена", "Старые контакты" и "См. Обратную сторону". Одна вещь, которая останется постоянной, состоит в том, что числа, которые я ищу, всегда будут иметь 4 числа, но может быть 1 строка или 10 строк.
Кто-нибудь знает, как я буду заниматься этой проблемой? Я думал что-то с точки зрения, возможно, находя только числа внутри строки, а затем проверяя, какие числа имеют промежутки между ними.
Спасибо
Ответы
Ответ 1
Вы можете использовать наборы символов для разделения строки, а затем определить, есть ли 4 числа в каждом компоненте. Это будет работать только в том случае, если строка содержит символы новой строки (\n
) в нем (как указывает ваш ответ на Lance).
Вот как я это сделаю:
NSString *test1= @"Contact Names\n
67-444-322\n
Dec 21 2012\n
23941 6745 9145072 01567\n
5511 23345 614567 123456\n
Older Contacts\n
See Back Side";
NSArray *lines = [test1 componentsSeparatedByCharactersInSet:[NSCharacterSet newlineCharacterSet];
// lines now contains each line in test1
for (NSString* line in lines) {
NSArray *elements = [line componentsSeparatedByCharactersInSet:[NSCharacterSet whitespaceCharacterSet];
if (elements.count == 4) {
// This line contains 4 numbers
// convert each number string into an int if needed
}
}
Извините за длинные строки кода, некоторые из селекторов Apple немного на длинной стороне... В любом случае, если элементы имеют 4 отдельных объекта (NSString
), то это одна из строк, которые вы ищете и вы можете манипулировать данными по мере необходимости.
ИЗМЕНИТЬ (в сторону):
По теме Regex (так как этот вопрос содержит тег regex
), да, вы можете использовать регулярные выражения, но Objective-C на самом деле не имеет "приятного" способа их обработки... Regex is more в области языков сценариев и языков, которые имеют встроенную поддержку для него.
Ответ 2
Я пробовал следующее и работает:
NSString *test1= @"Contact Names\n"
"67-444-322\n"
"Dec 21 2012\n"
"23941 6745 9145072 01567\n"
"5511 23345 614567 123456\n"
"Older Contacts\n"
"See Back Side";
NSString *pattern = @"(([0-9]+ ){3}+[0-9]+)(\\n(([0-9]+ ){3}+[0-9]+))*";
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:pattern options:0 error:nil];
NSArray *results = [regex matchesInString:test1 options:0 range:NSMakeRange(0, [test1 length])];
if ([results count] > 0) {
NSTextCheckingResult *result = [results objectAtIndex:0];
NSString *match = [test1 substringWithRange:result.range];
NSLog(@"\n%@", match); // These are your numbers
}
(Он также работает, если имеется только одна строка чисел.)
Ответ 3
Я уточнил свой код, чтобы он был более читабельным и остановился, когда он найдет строку (не врывается в строки... если вам это нужно, скажите мне снова добавить код или помочь вам, если это будет трудно)
Используемое регулярное выражение:
- Один или несколько номеров, за которыми следует одно или несколько пробелов (дерево раз все это)
- Один или несколько номеров, за которыми следует одно или несколько пробелов (тезисы - это изменения строк, вкладки, пробелы и т.д.)
-Я пытаюсь найти, что весь этот образец повторяется 1 или более раз
Код
NSString *test1= @"Contact Names\n 67-444-322\n\nDec 21 2012\n23941 6745 9145072 01567\n5511 23345 614567 123456\nOlder Contacts\nSee Back Side\n";
//create the reg expr
NSString *pattern1 = @"(([0-9]+ +){3}[0-9]+\\s+)+";
NSRegularExpression *regex1 = [NSRegularExpression regularExpressionWithPattern:pattern1 options:0 error:nil];
//find matches
NSArray *results1 = [regex1 matchesInString:test1 options:0 range:NSMakeRange(0, [test1 length])];
if ([results1 count] > 0) {
//if i find more series...what should i do?
if ([results1 count] > 1) {
NSLog(@"I found more than one matching series....what should i do?!");
exit(111);
}
//find series and print
NSTextCheckingResult *resultLocation1 = [results1 objectAtIndex:0];
NSString *match1 = [test1 substringWithRange:resultLocation1.range];
//trim leading and ending whitespaces
match1=[match1 stringByTrimmingCharactersInSet:
[NSCharacterSet whitespaceAndNewlineCharacterSet]];
NSLog(@"the series is \n%@", match1);
}else{
NSLog(@"No matches found in string");
}
Надеюсь, что это поможет
Ответ 4
#include <stdio.h>
#include <string.h>
#include <pcre.h>
int main(int argc, char **argv)
{
const char *error;
int erroffset;
int ovector[186];
char re[8192]="";
char txt[]="Dec 21 2012 23941 6745 9145072 01567 5511 23345 614567 123456 Ol\";";
char re1[]=".*?"; // Non-greedy match on filler
strcat(re,re1);
char re2[]="\\d+"; // Uninteresting: int
strcat(re,re2);
char re3[]=".*?"; // Non-greedy match on filler
strcat(re,re3);
char re4[]="\\d+"; // Uninteresting: int
strcat(re,re4);
char re5[]=".*?"; // Non-greedy match on filler
strcat(re,re5);
char re6[]="(\\d+)"; // Integer Number 1
strcat(re,re6);
char re7[]="(\\s+)"; // White Space 1
strcat(re,re7);
char re8[]="(\\d+)"; // Integer Number 2
strcat(re,re8);
char re9[]="(\\s+)"; // White Space 2
strcat(re,re9);
char re10[]="(\\d+)"; // Integer Number 3
strcat(re,re10);
char re11[]="(\\s+)"; // White Space 3
strcat(re,re11);
char re12[]="(\\d+)"; // Integer Number 4
strcat(re,re12);
char re13[]="(\\s+)"; // White Space 4
strcat(re,re13);
char re14[]="(\\d+)"; // Integer Number 5
strcat(re,re14);
char re15[]="(\\s+)"; // White Space 5
strcat(re,re15);
strcat(re,re16);
char re17[]="(\\s+)"; // White Space 6
strcat(re,re17);
char re18[]="(\\d+)"; // Integer Number 7
strcat(re,re18);
char re19[]=".*?"; // Non-greedy match on filler
strcat(re,re19);
char re20[]="(\\d+)"; // Integer Number 8
strcat(re,re20);
pcre *r = pcre_compile(re, PCRE_CASELESS|PCRE_DOTALL, &error, &erroffset, NULL);
int rc = pcre_exec(r, NULL, txt, strlen(txt), 0, 0, ovector, 186);
if (rc>0)
{
char int1[1024];
pcre_copy_substring(txt, ovector, rc,1,int1, 1024);
printf("(%s)",int1);
char ws1[1024];
pcre_copy_substring(txt, ovector, rc,2,ws1, 1024);
printf("(%s)",ws1);
char int2[1024];
pcre_copy_substring(txt, ovector, rc,3,int2, 1024);
printf("(%s)",int2);
char ws2[1024];
pcre_copy_substring(txt, ovector, rc,4,ws2, 1024);
printf("(%s)",ws2);
char int3[1024];
pcre_copy_substring(txt, ovector, rc,5,int3, 1024);
printf("(%s)",int3);
char ws3[1024];
pcre_copy_substring(txt, ovector, rc,6,ws3, 1024);
printf("(%s)",ws3);
char int4[1024];
pcre_copy_substring(txt, ovector, rc,7,int4, 1024);
printf("(%s)",int4);
char ws4[1024];
pcre_copy_substring(txt, ovector, rc,8,ws4, 1024);
printf("(%s)",ws4);
char int5[1024];
pcre_copy_substring(txt, ovector, rc,9,int5, 1024);
printf("(%s)",int5);
char ws5[1024];
pcre_copy_substring(txt, ovector, rc,10,ws5, 1024);
printf("(%s)",ws5);
char int6[1024];
pcre_copy_substring(txt, ovector, rc,11,int6, 1024);
printf("(%s)",int6);
char ws6[1024];
pcre_copy_substring(txt, ovector, rc,12,ws6, 1024);
printf("(%s)",ws6);
char int7[1024];
pcre_copy_substring(txt, ovector, rc,13,int7, 1024);
printf("(%s)",int7);
char int8[1024];
pcre_copy_substring(txt, ovector, rc,14,int8, 1024);
printf("(%s)",int8);
puts("\n");
}
}
В следующий раз используйте http://txt2re.com
а также вы можете создать простую строку регулярного выражения. Для этого вы можете записать их только в 1 переменную char.
Ответ 5
Создайте массив с именами всех месяцев месяца monthArray.
Затем разделите всю строку, используя пробел. Теперь внутри проверки цикла
если (четыре последовательных элемента расщепляемого массива являются числами)
{
if(previous 5th, 6th and seventh element in the splited array does not belong to monthArray)//if forloop count is 7 then previous 5th means the 2nd element in the splited array
{
those 4 consecutive variable belongs to a row you are looking for.
}
}
//--------------------------------------------- -------------
NSArray *monthArray = [[NSArray alloc] initWithObjects:@"Dec", nil];//here you have to add the 12 monts name. Now i added only 'Dec'
NSString *test1= @"Contact Names 67-444-322 Dec 21 2012 23941 6745 9145072 01567 5511 23345 614567 123456 Older Contacts See Back Side";
NSArray *splitArray = [test1 componentsSeparatedByString:@" "];
int count = 0;
for (int i =0; i<splitArray.count; i++) {
if ([[[splitArray objectAtIndex:i] componentsSeparatedByCharactersInSet:[[NSCharacterSet decimalDigitCharacterSet] invertedSet]] count]==1)//checks if it is a pure integer
{
count ++;
}else count= 0;
if (count>=4) {
if (i-4>=0) {
if ([monthArray containsObject:[splitArray objectAtIndex:i-4]]) {
continue;
}
}
if (i-5>=0) {
if ([monthArray containsObject:[splitArray objectAtIndex:i-5]]) {
continue;
}
}
NSLog(@"myneededRow===%@ %@ %@ %@",[splitArray objectAtIndex:i-3],[splitArray objectAtIndex:i-2],[splitArray objectAtIndex:i-1],[splitArray objectAtIndex:i]);
count = 0;
}
}
Ответ 6
Если количество чисел никогда не изменяется, то есть [5 чисел] [пробел] [4 числа] [пробел]...
Затем вы можете использовать NSRegularExpression, чтобы установить шаблон, а затем выполнить поиск строки для шаблона.
https://developer.apple.com/library/mac/#documentation/Foundation/Reference/NSRegularExpression_Class/Reference/Reference.html
Ответ 7
Попробуйте класс NSLingustic Tagger.
NSMutableArray numbers = [NSMutableArray new];
NSString *test1= @"Contact Names
67-444-322
Dec 21 2012
23941 6745 9145072 01567
5511 23345 614567 123456
Older Contacts
See Back Side";
NSLinguisticTaggerOptions options = NSLinguisticTaggerOmitWhitespace | NSLinguisticTaggerOmitPunctuation | NSLinguisticTaggerJoinNames;
NSLinguisticTagger *tagger = [[NSLinguisticTagger alloc] initWithTagSchemes: [NSLinguisticTagger availableTagSchemesForLanguage:@"en"] options:options];
tagger.string = test1;
[tagger enumerateTagsInRange:NSMakeRange(0, [test1 length]) scheme:NSLinguisticTagSchemeNameTypeOrLexicalClass options:options usingBlock:^(NSString *tag, NSRange tokenRange, NSRange sentenceRange, BOOL *stop) {
NSString *token = [test1 substringWithRange:tokenRange];
if(Tag == NSLinguisticTagNumber){
[numbers addObject:token];
}
}];
NSLogs("All Numbers in my strings are: %@", numbers);
Ответ 8
Это должно сработать. Я должен был добавить новые строки \n к вашему вводу, чтобы заставить мой работать, но я предполагаю, что вы получаете строку из API или файла, поэтому у него должны быть новые строки.
NSString *test1= @"Contact Names\
67-444-322\n\
Dec 21 2012\n\
23941 6745 9145072 01567\n\
5511 23345 614567 123456\n\
Older Contacts\n\
See Back Side";
// first, separate by new line
NSArray* allLinedStrings =
[test1 componentsSeparatedByCharactersInSet:[NSCharacterSet newlineCharacterSet]];
NSRegularExpression *regex = [[NSRegularExpression alloc] initWithPattern:@"^[0-9 ]+$"
options:0
error:nil];
for (NSString *line in allLinedStrings) {
NSArray *matches = [regex matchesInString:line options:0 range:NSMakeRange(0, [line length])];
if (matches.count) {
NSTextCheckingResult *result = matches[0];
NSString *match = [line substringWithRange:result.range];
NSLog(@"match found: %@\n", match);
}
}