使用带正则表达式的sscanf输入

时间:2014-06-30 04:49:17

标签: c scanf

我想要输入字符串的特定部分,如

  

“First(helloWorld):last”

从那个字符串我想通过正则表达式输入“helloWorld”。我正在使用

  

%* [^(](%s):“

但这不符合我的目的。请有人帮我解决这个问题。

2 个答案:

答案 0 :(得分:5)

scanf函数族中的格式说明符通常不被认为是正则表达式。

但是,你可以做你想要的事情。

#include <stdio.h>

int main() {
  char str[256];
  scanf("First (helloWorld): last", "%*[^(](%[^)]%*[^\n]", str);
  printf("%s\n", str);
  return 0;
}

%*[^(]   read and discard everything up to opening paren
(        read and discard the opening paren
%[^)]    read and store up up to (but not including) the closing paren
%*[^\n]  read and discard up to (but not including) the newline

上述sscanf的上下文中不需要最后一个格式说明符,但如果从流中读取并且您希望它位于当前行的末尾以进行下一次读取,则会很有用。请注意,换行符仍然保留在流中。

不是使用fscanf(或scanf)直接从流中读取,而是使用fgets更好地读取一行,然后提取字段感兴趣sscanf

// Read lines, extracting the first parenthesized substring.
#include <stdio.h>

int main() {
  char line[256], str[128];

  while (fgets(line, sizeof line, stdin)) {
    sscanf(line, "%*[^(](%127[^)]", str);
    printf("|%s|\n", str);
  }

  return 0;
}

示例运行:

one (two) three
|two|
four (five) six
|five|
seven eight (nine) ten
|nine|

答案 1 :(得分:1)

抱歉,标准C中没有真正的正则表达式解析器。

使用scanf()系列中的格式不是一个完整的正则表达式,但可以完成这项工作。 "%n"告诉sscanf()保存当前的扫描偏移量。

#include <stdio.h>
#include <stdlib.h>
char *foo(char *buf) {
  #define NotOpenParen "%*[^(]"
  #define NotCloseParen "%*[^)]"
  int start;
  int end = 0;

  sscanf(buf, NotOpenParen "(%n" NotCloseParen ")%n", &start, &end);
  if (end == 0) {
    return NULL; // End never found
  }
  buf[end-1] = '\0'; 
  return &buf[start];
}

// Usage example
char buf[] = "First (helloWorld): last";
printf("%s\n", foo(buf));

但这种方法失败了&#34; First():last&#34;。需要更多代码 一对strchr()电话更好。

char *foo(char *buf) {
  char *start = strchr(buf, '(');
  if (start == NULL)  {
    return NULL; // start never found
  }
  char *end = strchr(start, ')');
  if (end == NULL)  {
    return NULL; // end never found
  }
  *end = '\0'; 
  return &start[1];
}

否则,需要使用不属于C-spec的解决方案。