You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

正则表达式是否支持短路求值?SQLite Tcl中如何实现无捕获匹配?

问题与解答

需求背景

在SQLite Tcl接口中定义应用函数,用于WHERE子句判断JSON数组$jarray是否包含JSON数组$jnodes中的任意元素,仅返回0/1。需要解决两个问题:

  • 编写无捕获组的正则表达式(原代码用了捕获组,去掉括号无法得到正确结果)
  • 了解正则是否支持短路求值,以及如何实现

用户原代码及测试如下:

proc InJSONArray {jarray jnodes} {
  #set $node [join [split [string range $p 1 end-1] ,] |]
  set rnodes [string map {, |} [string range $jnodes 1 end-1] ]
  return [regexp "(\\\[|,)($rnodes)(,|\\\])" $jarray]
}

set j {[22,18,49,76,37,45,16]}
set n1 {[12,58,93,67]}; # 无匹配,返回0
set n2 {[32,84,37,14]};  # 匹配37,返回1

InJSONArray $j $n1  
# 输出:0
InJSONArray $j $n2
# 输出:1  

用户还做了性能对比,循环实现和正则性能相近:

proc Intersect {jarray jnodes} {
  set nodes [split [string range $jnodes 1 end-1] ,]
  set array [split [string range $jarray 1 end-1] ,]
  foreach n $nodes {
    if { $n in $array } {return 1}
  }
  return 0
}
proc InJSONArray {jarray jnodes} {
  return [regexp "(\\\[|,)([string map {, |} [string range $jnodes 1 end-1] ])(,|\\\])" $jarray]
}
set j {[22,18,49,76,37,45,16]}
set n1 {[12,58,93,67]}; # 无匹配
set n2 {[32,84,37,14]};  # 匹配37

% timerate {Intersect $j $n1} 5000
1.932625 µs/# 2587155 # 517431 #/sec 5000.000 net-ms
% timerate {Intersect $j $n2} 5000
1.835088 µs/# 2724665 # 544933 #/sec 5000.000 net-ms
% timerate {InJSONArray $j $n1} 5000
1.779623 µs/# 2809584 # 561916 #/sec 5000.000 net-ms
% timerate {InJSONArray $j $n2} 5000
1.617978 µs/# 3090277 # 618055 #/sec 5000.000 net-ms

解决方案

1. 无捕获组的正则写法

原代码中的括号()会创建捕获组,若要保留分组逻辑但不捕获内容,需使用非捕获组(?:...)。非捕获组仅用于定义匹配逻辑,不会保存匹配的子串,完全满足需求。

修改后的函数:

proc InJSONArray {jarray jnodes} {
  set rnodes [string map {, |} [string range $jnodes 1 end-1] ]
  # 用(?:...)替代(),消除捕获组
  return [regexp "(?:\\\[|,)(?:$rnodes)(?:,|\\\])" $jarray]
}

测试验证:调用该函数仍会正确返回0或1,且不会产生任何捕获组。

2. 正则的短路求值实现

Tcl的regexp命令默认是非全局匹配模式,只要找到第一个符合正则的子串,就会立即返回结果并停止扫描整个字符串,这就是天然的短路求值行为,无需额外配置。

当前的正则逻辑已经是按从左到右的顺序匹配数组元素,一旦找到第一个匹配的节点就会停止搜索,和循环中return 1的短路效果一致。


内容的提问来源于stack exchange,提问作者Gary

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.01 21:57:26