【问题标题】:Input using sscanf with regular expression使用带有正则表达式的 sscanf 输入
【发布时间】:2014-06-30 04:49:17
【问题描述】:

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

“第一个(helloWorld):最后一个”

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

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

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

【问题讨论】:

  • scanf 不做正则表达式。
  • 我想要它使用正则表达式。只能通过正则表达式来实现吗?
  • 然后使用正则表达式库; scanf 不执行此操作。
  • @Md Salman Ahmed 注意到您发布了 8 个问题,但没有接受任何问题。推荐阅读stackoverflow.com/help/someone-answers

标签: c scanf


【解决方案1】:

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|

【讨论】:

    【解决方案2】:

    抱歉,标准 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));
    

    但是这种方法在“First (): last”上失败了。需要更多代码。
    一对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 规范的解决方案。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-06-18
      • 1970-01-01
      • 1970-01-01
      • 2013-08-28
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多