正则表达式如何匹配?

时间:2017-04-18 06:53:29

标签: regex string

最近在一次采访中,我被问到一个问题,即我有一个字符串,其中包含数十亿个字符。该字符串中包含ASCII和非ASCII字符。任务是删除所有非ASCII字符,在输出中,字符串必须只包含ASCII字符。解决方案必须是一种时间有效的算法。

我提出了两种方法:

  1. 创建一个ASCII字符数组。如果当前字符是ASCII字符数组,则循环检查字符串。如果是,则跳过或用null替换它。
  2. 显然,这不是一个节省时间的解决方案。

    1. 其次,我建议如果我们将数组分成两半再分一半等等。我仍然会像上面的方法一样检查ASCII字符。
    2. 这次谈话导致了一个讨论,在那里面试官正在寻找一个解决方案,在这个解决方案中,我们不必逐字逐句,他建议使用正则表达式。

      我的问题是,当我们使用正则表达式匹配模式时,它会逐字符检查字符串,还是会使用其他方法。我确信正则表达式将逐个字符地查找/匹配。 任何人都可以清楚我的怀疑吗? 感谢

2 个答案:

答案 0 :(得分:1)

你可以使用这样的范围:

[\x20-\x7E]

此范围匹配[space]到〜中的每个字符。可打印的ascii范围。

答案 1 :(得分:0)

正则表达式确实对匹配一系列字符的情况使用优化:简单解释一下,如果你正在寻找"XXXXXXX",你知道你可以测试每个第7个字符,只看看一旦你在那里找到X,就越近了。但是,您需要过滤每个单个字符:这意味着,正则表达式不会更有效(实际上效率会降低,因为您需要进出regexp来处理您的发现)。

相反,有效的方法(假设类似C的架构)将从两个索引(源和结果)开始为零,并处理字符串:如果字符具有高位清除,则它是' s ASCII:从源复制到结果,递增两个索引。如果设置了高位,则它是非ASCII的:只增加源索引。

void removeNonAscii(char *str) {
  int s, r;
  for (s = 0, r = 0; str[s]; s++) {
    if (!(str[s] & 128)) {
      str[r++] = str[s];
    }
  }
  str[r] = 0;
}

(或者您可以通过复制到新字符串而不是覆盖当前字符串来制作非破坏性字符串;算法是相同的。)