📄 string.c
字号:
} status->expression.re_nsub++; } if(replacement!=NULL && (status->replacement==NULL || strcmp(status->replacement,replacement)!=0)) { status->replacement=replacement; status->between_replacements=vector_new(16); status->replacement_mapping=_vector_new(16, sizeof(int32_t)); const char* current=replacement; const char* last_current=replacement; while(*current!='\0') { if(*current=='$' && *(current+1)>='1' && *(current+1)<='9') { if(current!=replacement && *(current-1)=='\\') { vector_push(status->between_replacements, string_new_from_to(last_current, 0, current-last_current-1)); int32_t id=-1; _vector_push(status->replacement_mapping, &id); last_current=current; } else { vector_push(status->between_replacements, string_new_from_to(last_current, 0, current-last_current)); last_current=current+2; while(*last_current>='1' && *(last_current)<='9')last_current++; string_t* group_id=string_new_from_to(current, 1, last_current-current); int32_t id=string_to_int32(group_id); if(id<1 || id>status->expression.re_nsub)warn("invalid group replacement \"$%s\", s/%s/%s/%s, %d group%s", group_id->data, pattern, replacement, flags_string, status->expression.re_nsub-1,status->expression.re_nsub-1>1?"s":""); _vector_push(status->replacement_mapping, &id); string_free(group_id); current=last_current-1; } } current++; } vector_push(status->between_replacements, string_new_from_to(last_current, 0, current-last_current)); vector_optimize(status->between_replacements); vector_optimize(status->replacement_mapping); } return status;}vector_t* string_match(string_t* input, const char* pattern, const char* flags){ regexstatus_t* status=_regexstatus_new(pattern, NULL, flags); int regex_flags=0; if(status->end!=0)regex_flags|=REG_NOTBOL; regex_flags|=REG_STARTEND; if((status->flags & REGEX_FLAG_CONTINUE) == 0) { status->start=0; status->end=0; } regmatch_t match[status->expression.re_nsub]; match[0].rm_so=status->end; match[0].rm_eo=input->length; int result=regexec(&status->expression,input->data,status->expression.re_nsub,match,regex_flags); vector_t* groups=NULL; if(((result==0 && (status->flags & REGEX_FLAG_REVERSE)==0)) || (result!=0 && (status->flags & REGEX_FLAG_REVERSE)==1)) { if(status->flags & REGEX_FLAG_NOSUB) { groups=(vector_t*)1; } else { groups=vector_new(status->expression.re_nsub); groups->length=status->expression.re_nsub; size_t i=0; for(i=0;i<status->expression.re_nsub;i++) { vector_set(groups,i,string_new_from_to(input->data,match[i].rm_so,match[i].rm_eo)); } status->start=match[0].rm_so; status->end=match[0].rm_eo; } }#ifdef STRING_REGEX_USE_CACHE if(status->flags & REGEX_FLAG_ONCE)#endif _regexstatus_free(status); return groups;}array_t* string_split(string_t* input, const char* separator, const char* flags){ array_t* output=array_new(); regexstatus_t* status=_regexstatus_new(separator, NULL, flags); regmatch_t match[status->expression.re_nsub]; match[0].rm_so=0; match[0].rm_eo=input->length; regoff_t last_start=0; while(regexec(&status->expression,input->data,status->expression.re_nsub,match,REG_STARTEND)==0) { if(match[0].rm_so!=0)array_push(output,string_new_from_to(input->data,last_start,match[0].rm_so)); last_start=match[0].rm_eo; match[0].rm_so=match[0].rm_eo; match[0].rm_eo=input->length; } if(last_start!=input->length)array_push(output,string_new_from_to(input->data,last_start,input->length));#ifdef STRING_REGEX_USE_CACHE if(status->flags & REGEX_FLAG_ONCE)#endif _regexstatus_free(status); return output;}array_t* string_array_grep(array_t* input, const char* pattern, const char* flags){ array_t* output=NULL; regexstatus_t* status=_regexstatus_new(pattern, NULL, flags); int i=0; for(i=0;i<input->length;i++) { string_t* string=array_get(input,i); int result=regexec(&status->expression,string->data,0,NULL,0); if(string!=NULL && ((result==0 && (status->flags & REGEX_FLAG_REVERSE)==0) || (result!=0 && (status->flags & REGEX_FLAG_REVERSE)!=0))) { if(output==NULL)output=array_new(); array_push(output, string_copy(string)); } }#ifdef STRING_REGEX_USE_CACHE if(status->flags & REGEX_FLAG_ONCE)#endif _regexstatus_free(status); return output;}int string_replace(string_t* input, const char* pattern, const char* replacement, const char* flags){ regexstatus_t* status=_regexstatus_new(pattern, replacement, flags); regmatch_t match[status->expression.re_nsub]; match[0].rm_so=0; match[0].rm_eo=input->length; regoff_t last_start=0; int i; int matched=0; array_t* output=array_new(); while(regexec(&status->expression,input->data,status->expression.re_nsub,match,REG_STARTEND)==0) { if(match[0].rm_so!=0)array_push(output,string_new_from_to(input->data,last_start,match[0].rm_so)); for(i=0; i<status->replacement_mapping->length; i++) { array_push(output,string_copy(vector_get(status->between_replacements, i))); int32_t* id=_vector_get(status->replacement_mapping, i); if(*id>0 && *id<status->expression.re_nsub) array_push(output,string_new_from_to(input->data, match[*id].rm_so, match[*id].rm_eo)); } array_push(output,string_copy(vector_get(status->between_replacements, status->between_replacements->length-1))); last_start=match[0].rm_eo; match[0].rm_so=match[0].rm_eo; match[0].rm_eo=input->length; matched=1; if((status->flags & REGEX_FLAG_GLOBAL) == 0)break; } if(matched) { if(last_start!=input->length)array_push(output,string_new_from_to(input->data,last_start,input->length)); string_t* joint_output=string_join_cstr("",output); FREE(input->data); input->data=joint_output->data; input->length=joint_output->length; input->size=joint_output->size; FREE(joint_output); } string_array_free(output);#ifdef STRING_REGEX_USE_CACHE if(status->flags & REGEX_FLAG_ONCE)#endif _regexstatus_free(status); return matched;}void string_array_free(array_t* input){ size_t i; for(i=0;i<input->length;i++) { string_free((string_t*)array_get(input,i)); } array_free(input);}void string_vector_free(vector_t* input){ size_t i; for(i=0;i<input->length;i++) { string_free((string_t*)vector_get(input,i)); } vector_free(input);}int32_t string_to_int32(string_t* input){ char* error=NULL; int32_t output=strtol(input->data,&error,10); if(error!=NULL && *error=='\0')return output; warn("string_to_int32(%s) failed",input->data); return 0;}int64_t string_to_int64(string_t* input){ char* error=NULL; int64_t output=strtoll(input->data,&error,10); if(error!=NULL && *error=='\0')return output; warn("string_to_int64(%s) failed",input->data); return 0;}double string_to_double(string_t* input){ char* error=NULL; double output=strtod(input->data,&error); if(error!=NULL && *error=='\0')return output; warn("string_to_double(%s) failed",input->data); return NAN;}float string_to_float(string_t* input){ char* error=NULL; float output=strtof(input->data,&error); if(error!=NULL && *error=='\0')return output; warn("string_to_float(%s) failed",input->data); return 0;}// faster without GC which forces to duplicate memorystring_t* string_sprintf(const char* format, ...){ string_t* output=(string_t*)MALLOC(sizeof(string_t)); int result=0; va_list argument_list; va_start(argument_list, format);#ifdef USE_GC char* temp; result=vasprintf(&temp, format, argument_list); output->data=GC_STRDUP(temp); free(temp);#else result=vasprintf(&output->data, format, argument_list);#endif va_end(argument_list); if(result==-1 || output->data==NULL)warn("string_sprintf() failed"); output->length=strlen(output->data); output->size=output->length+1; return output;}void string_array_fprintf(FILE* stream, const char* format, array_t* array){ int i; for(i=0;i<array->length;i++) { string_t* string=array_get(array, i); fprintf(stream, format, string->data); }}array_t* string_argv_to_array(int argc, char** argv){ array_t* output=array_new(); int i; for(i=1; i<argc; i++) { array_push(output,string_new(argv[i])); } return output;}int string_compare(string_t* a, string_t* b){ return strcmp(a->data, b->data);}int string_equal(string_t* a, string_t* b){ return strcmp(a->data, b->data)==0;}int string_not_equal(string_t* a, string_t* b){ return strcmp(a->data, b->data)!=0;}int string_compare_cstr(string_t* a, const char* b){ return strcmp(a->data, b);}int string_equal_cstr(string_t* a, const char* b){ return strcmp(a->data, b)==0;}int string_not_equal_cstr(string_t* a, const char* b){ return strcmp(a->data, b)!=0;}string_t* string_readline(FILE* file){ string_t* output=NULL; char buffer[1024]; do { char* result=fgets(buffer,1024,file); if(result==NULL)return output; if(output==NULL) output=string_new(buffer); else string_append_cstr(output,buffer); } while(strlen(buffer)==1023 && buffer[1022]!='\n'); return output;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -