2017-08-24 56 views
-7

假設我的字符串是:haha "lol"
我想只提取lol如何提取C中沒有正則表達式的字符串中的雙引號之間的文本?

#include<stdio.h> 

int main() { 
    char a[20]={0}; 
    char *s="haha \"lol\""; 
    if(sscanf(s,"%*[^\"]'%[^\"]\"",a)==1){ 
     printf("Found stuff inside quotes"); 
    } 
} 
+2

而且問題出在哪裏?向我們展示您嘗試過的方式以及卡住的位置。 –

+0

我試過了: #include int main(){ char a [20] = {0}; char * s =「echo」foobar \「| cat」; (printf(「print stuff inside inside double-quotes」); } }(sscanf(s,「%* [^ \」]'%[^ \「] \」「,a)== 1){ } } 但這不起作用 – fredj0hnson

+0

我不認爲寫實際代碼來迭代/解析字符串會被認爲是有用的:( –

回答

2

通過施加適當的解析器爲您解析的源語言。

解析輸入的單行程通常很脆弱,很難正確。

這就是說,你可以嘗試的東西像

const char *input = "haha \"lol\""; 
char quoted[32]; 

if(sscanf(input, "%*[^\"]\"%31[^\"]\"", quoted) == 1) 
{ 
    printf("got '%s'\n", quoted); 
} 

這應該被硬化,但也足以讓你開始。

+1

輕微:失敗,使用'「\」lol \「」'。(第一個字符是'''。) – chux

+0

@chux這是一個很好的觀點,我不會編輯修正,因爲這也是我的觀點(部分):)使用'strchr()'可能會更好。 – unwind

+0

謝謝!請問我可以在哪裏瞭解更多有關sscanf和第3行的內容? – fredj0hnson

0

我認爲這是足夠的unwind答案(即使你根據需要添加代碼)

相似,這個問題已經存在的一個問題。
Split unquoted string in C

當使用這種方法,你可以寫如下:

#include <stdio.h> 
#include <string.h> 
#include <stdlib.h> 

#define ESCAPE '\\' //ESCAPE CHARACTER 

typedef struct token { 
    const char *top; 
    const char *end;//point to next character 
} Token; 

Token getToken(const char **sp, char sep){ 
    const char *s = *sp; 
    const char *top, *end; 
    Token token = { NULL, NULL}; 

    while(*s && *s == sep)//skip top separators 
     ++s; 
    if(!*s){ 
     *sp = s; 
     return token; 
    } 
    token.top = s; 
    while(*s && *s != sep){ 
     if(*s == ESCAPE) 
      ++s; 
     else if(*s == '"'){ 
      char *p = strchr(s + 1, '"');//search end '"' 
      while(p && p[-1] == ESCAPE) 
       p = strchr(p + 1, '"'); 
      if(p) 
       s = p; 
     } 
     ++s; 
    } 
    token.end = s; 
    *sp = s; 

    return token; 
} 

char *remove_escape(char *s){ 
    char *from, *to; 
    from = to = s; 
    while(*from){ 
     if(*from != ESCAPE) 
      *to++ = *from; 
     ++from; 
    } 
    *to = 0; 
    return s; 
} 

char *ft_strsub(Token token){ 
    size_t len = token.end - token.top; 
    char *sub = malloc(len + 1);//check return value 
    if (sub){ 
     memcpy(sub, token.top, len); 
     sub[len] = 0; 
    } 
    return sub; 
} 

int main(int argc, char **argv){ 
    char *str = NULL; 
    const char *s="haha \"lol\""; 

    Token token = getToken(&s, ' '); 

    while(token.top != NULL){ 
     str = ft_strsub(token); 
     remove_escape(str); 
     if(*str == '"')//find it! 
      break; 
     free(str); 
     token = getToken(&s, ' '); 
    } 
    if(str){ 
     printf("Found stuff inside quotes: "); 
     //remove " 
     size_t len = strlen(str); 
     str[len-1] = 0; 
     printf("'%s'\n", str + 1);//ignore first character or use memmove 
     free(str); 
    } 

    return 0; 
} 
1

有時候一些代碼走一段很長的路要走。所有需要的是2個電話strchr()

extract_quoted_string()更改爲僞代碼。

const char *extract_quoted_string(const char *s, size_t *sz) { 
    const char *left = look_for_quote_start_at_s; 
    if (failure?) { 
    return NULL; 
    } 
    Update_left_to_the_next_possible_position 
    const char *right = look_for_quote_start_at_updated_left; 
    if (failure?) { 
    return NULL; 
    } 
    Compute_and_save_size_based_on_left_and_right 
    return left; 
} 

測試工具

void test(const char *s) { 
    printf("<%s> --> ", s); 
    size_t sz; 
    const char *extract = extract_quoted_string(s, &sz); 
    if (extract) { 
    printf("<%.*s>\n", (int) sz, extract); 

    } else { 
    printf("None\n"); 
    } 
} 

int main() { 
    test(""); 
    test("123"); 
    test("\"123"); 
    test("123\""); 
    test("\"123\""); 
    test("abc\"123"); 
    test("abc\"123\""); 
    test("123\"xyz"); 
    test("\"123\"xyz"); 
    test("abc\"123\"xyz"); 
} 

預計輸出

<> --> None 
<123> --> None 
<"123> --> None 
<123"> --> None 
<"123"> --> <123> 
<abc"123> --> None 
<abc"123"> --> <123> 
<123"xyz> --> None 
<"123"xyz> --> <123> 
<abc"123"xyz> --> <123> 
相關問題