【问题标题】:Pure C string-replace for a whole word纯 C 字符串替换整个单词
【发布时间】:2013-11-25 21:48:06
【问题描述】:

我无法替换句子中的整个单词。

例如:

替换:

  • thea
  • hellohi
  • housetree

输入:

你好,这里是房子。

输出:

你好,这是一棵树。

是否可以只使用<string.h> 库而不使用正则表达式等?

【问题讨论】:

  • 是的,有可能。
  • 是的,这是可能的 ;-)
  • 当然,很简单!

标签: c string replace word


【解决方案1】:

也许这可以帮助你 str-replace-c

【讨论】:

    【解决方案2】:

    完全有可能,但标准库没有任何函数可以直接支持它。因此,要做到这一点,您通常会使用 strstr 之类的东西来查找要替换的字符串的现有实例,memmove 来移动字符串的其余部分,并用所需的内容覆盖原始实例手动替换,或者使用strncpy

    请注意,在这种情况下,您的替换字符串都比它们要替换的原始字符串短。这意味着更换总是可以安全地完成。如果替换的长度比原来的长,您还必须做一些事情来跟踪最大字符串长度,并确保不超过它。

    哦,还有一点不太重要,但是如果您要搜索的内容是一个完整的单词,而不仅仅是在另一个单词中出现该字符串,您可能想要搜索 <space>word<space>,除非在字符串的开头或结尾,因此(例如)您不会将there 中的the 替换为a 并将第一个单词从there 转换为are

    【讨论】:

    • 一般会搜索<not-a-word>word<not-a-word>。构建“单词”字符列表很容易,同时它为您提供了“非单词”功能——字符串开头和字符串结尾除外。我同意其他人的观点:是的,这是可能的。
    • 对我的评论更好的表示法是 GREP,带有负面的后视/前瞻:(?<!\w)word(?!\w)。这是因为“左边没有单词字符”匹配'start-of-string',而“一个不是单词字符的字符”将。跨度>
    【解决方案3】:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <ctype.h>
    
    typedef struct pair {
        char *key;
        char *value;
    } Pair;
    
    int cmp(const void *a, const void *b){
        return strcmp(((const Pair*)a)->key, ((const Pair*)b)->key);
    }
    
    char *dictionary(const char *word){
        static const Pair table[] =
            {{"hello", "hi"}, {"house", "tree"},{"the", "a"}};
        char *p, *wk = strdup(word);
        Pair key, *pair;
    
        for(p=wk;*p;++p)
            *p = tolower(*p);
        key.key = wk;
        pair=bsearch(&key, table, sizeof(table)/sizeof(Pair), sizeof(Pair), cmp);
        free(wk);
        if(pair){
            wk=strdup(pair->value);
            if(isupper(*word))
                *wk = toupper(*wk);//capitalize
            return wk;
        }
    
        return NULL;
    }
    
    typedef char Type;
    
    typedef struct vector {
        size_t size;
        size_t capacity;
        Type *array;
    } Vector;
    
    Vector *vec_make(){
        Vector *v;
        v = (Vector*)malloc(sizeof(Vector));
        if(v){
            v->size = 0;
            v->capacity=16;
            v->array=(Type*)realloc(NULL, sizeof(Type)*(v->capacity += 16));
        }
        return v;
    }
    
    void vec_add(Vector *v, Type value){
        v->array[v->size] = value;
        if(++v->size == v->capacity){
            v->array=(Type*)realloc(v->array, sizeof(Type)*(v->capacity += 16));
            if(!v->array){
                perror("memory not enough");
                exit(-1);
            }
        }
    }
    void vec_adds(Vector *v, Type *values, size_t size){
        while(size--)
            vec_add(v, *values++);
    }
    
    char *convert(const char *str){
        static const char *delimiters = " \t\n,.!?";
        char *in = strdup(str);
        char *out;
        char *inp = in;
        Vector *v = vec_make();
    
        while(*inp){
            size_t size;
            if(size = strcspn(inp, delimiters)){
                char *word, *cnv_word;
                word = malloc(size+1);
                memcpy(word, inp, size);
                word[size]='\0';
                if(NULL==(cnv_word = dictionary(word)))
                    vec_adds(v, word, size);
                else
                    for(out = cnv_word; *out; ++out)
                        vec_add(v, *out);
                free(word);
                free(cnv_word);
                inp += size;
            }
            if(size = strspn(inp, delimiters)){
                vec_adds(v, inp, size);
                inp += size;
            }
        }
        vec_add(v, '\0');
        out = v->array;
        free(v);
        free(in);
    
        return out;
    }
    
    int main(void){
        char input[] = "Hello there, this is the house.";
        char *output = convert(input);
    
        puts(input);
        puts(output);
        free(output);
    
        return 0;
    }
    /* result
    Hello there, this is the house.
    Hi there, this is a tree.
    */
    

    【讨论】:

      【解决方案4】:

      创建之前和之后的哈希,即您要搜索的内容和要替换的内容,遍历字符串并使用 KMP 或 rabin karp 之类的内容搜索单词,并在哈希表中找到您需要的内容.

      【讨论】:

        猜你喜欢
        • 2011-03-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-03-29
        • 1970-01-01
        相关资源
        最近更新 更多