0

我正在寻找的内容基本上相当于提取括号之间的文本,这就是我将使用的示例。如果我的输入类似于(test 1 2)(test 3 4)test foo bar(test again)下面的代码,则返回我想要的内容:

token: test 1 2
token: test 3 4
token: test again

但如果我的输入是(test 1 (test 2 3)foo(bar test) again)我得到

token: test 1 
token: test 2 3
token: bar test

我不想看到test 1。是的,它在左括号和右括号之间,但这意味着在该位数据的上游出现了问题。

void print_tokens(char *s) {
    printf("input: %s\n",s);
    char *output;
    const char *valid = "abcdefghijklmnopqrstuvwxyz0123456789 ";
    unsigned int length;
    s=strchr(s,'(')+1;
    length=strspn(s,valid);
    while(s!=NULL && length>0) {
        output=malloc(length+1);
        strncpy(output,s,length);
        output[length]='\0';
        printf("token: %s\n",output);
        free(output);
        if(strchr(s,'(')!=NULL) {
            s=strchr(s,'(')+1;
            length=strspn(s,valid);
        } else {
            s=NULL;
        }
    }
}

除了在内存管理上相当松散之外,这种 slap-dash 方法可能“足够接近”,因为我有另一个函数(输出实际上会传递给它,它会对自己的输入进行一些检查,但这仍然可以让一些格式错误的表达式,如果可能的话,我想避免这种情况.虽然我正在寻找的东西可以很容易地用正则表达式来概括(/.*\(([a-z0-9 ]*?)\)/我相信),但它必须或多或少是标准的 C.GNU C ,Boost,以及我见过的大多数其他库,我无法获得字符串解析或正则表达式的帮助。

是否有更好的方法来提取此文本以消除无关标记?并且使用有效字符集更加灵活(例如,除了左右括号之外的所有内容)?

4

2 回答 2

1

这应该差不多做到:

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

void print_tokens(char *s)
{
    printf("input: %s\n", s);
    char *start = s;
    char *end = s;
    while(*s) {
        if(*s == '(') start = s;
        else if(*s == ')') end = s;
        if(start < end && *start) {
              *end = 0;
              printf("token: %s\n", start+1);
              start = s = end;
        }
        s++;
    }
}

int main()
{
    char str[] = "(test 1 (test 2 3)foo(bar test) again)";
    char str2[] = "(test 1 2)(test 3 4)test foo bar(test again)";
    print_tokens(str);
    print_tokens(str2);
    return 0;
}

它适用于您给我的两个测试用例。请注意,它会破坏原始字符串,因此如果您不希望它这样做,您应该添加一些代码来复制字符串。

于 2013-11-14T19:58:25.377 回答
0

蹩脚的伪代码:

  char *c = start;
  char *d;

  while (*c) {
    while (*c && *c != '(') c++;
    /* we found a left paren */
    d = ++c;
    while (*d && *d != ')') {
      if (*d == '(') {
        /* reset! */
        c = d;
        break;
      }
      if (*d == ')') {
        *d = 0;
        printf("token: %s\n", c);
        c = d;
        continue;
      }
      d++
    }
  }
  printf("finished\n");
于 2013-11-14T19:38:33.140 回答