将分隔符视为输入标记

Treat delimiters as input tokens

本文关键字:输入 分隔符      更新时间:2023-10-16

我想知道如何在C++和Java中同时做到这一点(编辑:我不是指同时做到。我问了两个类似的问题,"我如何在C++中做到这一步?"。

我想解析文件中的输入,并将"("answers")"作为除空白之外的分隔符。但我也希望"("或")"的每一次相遇都能被视为一个单独的象征。例如,在解析时

此重叠群(嵌套(括号))

我希望连续调用next(或>>)以提供(每行一个)

This
contains
(
nested
(
parentheses
)
)
<end of input>

是否有内置此功能的解析器/扫描仪?我知道Java的Scanner功能强大,但据我所知,每次遇到下一个令牌时,都无法确定哪个分隔符匹配。

编译器编译器讨论之外,这种解析器可以使用两个索引天真地实现,比如:

for(int i = 0; i < str.size(); ) {
  int j = i;
  for(; j < str.size(); ++j) {
    // check for spaces
    if(str[j] == ' ') {
      // capture substring index i to j-1 as a token
      i = j+1;
      break;
    }
    // check for brackets
    if(str[j] == '(' || str[j] == ')') {
      // str[j] is a token
      i = j+1;
      break;
    }
  }
  // no more characters to check
  if(j >= str.size()) break;
}

基本上,i是指示令牌开始的标记,j用于搜索令牌结束的位置。

免责声明:以上代码未经测试,可能包含语法错误和错误,尤其是在空输入、空格等情况下,并且在大数据上可能表现不佳。在重新设计轮子之前,请考虑使用第三方库。

或者,对于代码量最小的解决方案,您可以将每次出现的"("替换为"("(同样用")"),并进行空白标记:

str.replaceAll("(", " ( ").split("s+");

这应该可以通过正则表达式轻松处理。应该做一些类似"\\s*(?:(\\w+)|([()])"的东西C++11中的技巧(对于早期版本的C++,您需要Boost正则表达式)。Java也有正则表达式支持,所以你应该能够在那里做同样的事情。

在这两种情况下,上面的表达式都跳过空白,然后"捕获"第1组中的符号,或第2组中的括号。