Tools 是非官方社区Wiki。社区文档正在编写中,欢迎参与。 Wiki编辑答疑群:717421103
版本250923.2
全站通知:

帮助:解析函数/arraysearcharray

来自WIKI实验室WIKI_BWIKI_哔哩哔哩
跳到导航 跳到搜索
arraysearcharray 悬浮框🟢稳定可用
从数组中筛选匹配项并写入新数组
{{#arraysearcharray: 新数组名 | 原数组名 | 搜索条件 | 起始索引 | 限制数量 | 转换规则 }}
扩展:Arrays
数组
筛选
搜索
正则
相关函数
相关资源

arraysearcharray

数组筛选。出自扩展 Arrays BWIKI和各大Wiki平台广泛使用此扩展。<br>在遥远的未来,它可能与Mediawiki新的并行解析器不兼容,请参阅扩展主页了解更多信息。

从数组中筛选匹配项并写入新数组。比如从数组 apple, blue, fly, add, wiki 中筛选出以字母 a 开头的元素,写入新数组得到 apple, add;支持正则表达式匹配和捕获组替换。

通常用于需要对数组数据进行条件过滤的场景,如从 SMW 查询结果中提取符合特定模式的数据、清理数组中的空值、按规则重组数据格式等批处理操作。

语法

{{#arraysearcharray: 新数组名 | 原数组名 | 搜索条件 | 起始索引 | 限制数量 | 转换规则 }}

参数

新数组名
筛选结果将写入此数组(区分大小写)
原数组名
要被筛选的源数组名称
搜索条件
正则表达式或字符串,默认值 /^(\s*)$/(匹配空白项)
如果不是有效正则,会被转换为精确匹配:/^\s*(搜索内容)\s*$/
起始索引
可选,默认 0。从该位置开始扫描,支持负数(从末尾计数)
限制数量
可选,默认不限制。限制匹配结果的最大数量,空值或 -1 表示不限制
转换规则
可选,仅当搜索条件为正则时生效。对匹配文本做替换后再写入新数组
支持用 $0(整段匹配)、$1$2…(捕获组)引用匹配内容

效果

  • 输出:不输出任何字符
  • 效果:创建或更新指定名称的新数组变量,存储从原数组筛选出的匹配项;若原数组不存在或索引无效,则创建空数组


示例

定义数组:{{#arraydefine:a|apple, bule1, fly, add23,,,, wiki}},值为:apple、bule1、fly、add23、、、、wiki

说明 代码 结果(arrayprint)
筛选以 a 开头的元素 {{#arraysearcharray: x | a | /^a.+/ }} apple、add23
以 a 开头,从第 2 项开始 {{#arraysearcharray: x | a | /^a.+/ | 2 }} add23
以 a 开头,仅取 1 个 {{#arraysearcharray: x | a | /^a.+/ | 0 | 1 }} apple
匹配以数字结尾的元素 {{#arraysearcharray:x|a|/^.*?(\d+)$/}} bule1、add23
匹配并重新格式化 {{#arraysearcharray:x|a|/^.*?(\d+)$/|||'''pre-$0'''}} pre-bule1pre-add23
提取数字部分(捕获组) {{#arraysearcharray:x|a|/^.*?(\d+)$/|||编号:$1}} 编号:1、编号:23
删除空项(保留非空白) {{#arraysearcharray:a|a|/\S+/}} apple、bule1、fly、add23、wiki

边缘示例

说明 代码 效果
负索引从末尾开始 {{#arraysearcharray:x|a|/./|-3}} fly、add23、wiki
限制为 0 不返回结果 {{#arraysearcharray:x|a|/a/|0|0}}
非正则自动转换 {{#arraysearcharray:x|a|apple}} apple
新旧数组同名覆盖 {{#arraysearcharray:a|a|/\S+/}} apple、bule1、fly、add23、wiki

底层代码

/** mediawiki-extensions-Arrays-REL1_37 ExtArrays.php
 * search an array and create a new array with all the results. Transforming the new entries before storing them is possible too.
 * usage:
 *   {{#arraysearcharray:arrayid_new|arrayid|needle|index|limit|transform}}
 *
 * "needle" can be a regular expression or a string search value. If "needle" is a regular expression, "transform" can contain
 * "$n" where "n" stands for a number to access a variable from the regex result.
 */
public static function pfObj_arraysearcharray( Parser &$parser, PPFrame $frame, $args ) {
	$store = self::get( $parser );

	// get first two parameters
	$arrayId = isset( $args[1] ) ? trim( $frame->expand( $args[1] ) ) : null;
	$arrayId_new  = isset( $args[0] ) ? trim( $frame->expand( $args[0] ) ) : '';

	if ( $arrayId === null ) {
		global $egArraysCompatibilityMode;
		if ( !$egArraysCompatibilityMode ) { // COMPATIBILITY-MODE
			$store->setArray( $arrayId_new );
		}
		return '';
	}

	// Get Parameters the other parameters
	$needle       = isset( $args[2] ) ? trim( $frame->expand( $args[2] ) ) : '/^(\s*)$/';
	$index        = isset( $args[3] ) ? trim( $frame->expand( $args[3] ) ) : 0;
	$limit        = isset( $args[4] ) ? trim( $frame->expand( $args[4] ) ) : '';
	$rawTransform = isset( $args[5] ) ? $args[5] : null;

	// also takes care of negative index by calculating start index:
	$validIndex = $store->validate_array_index( $arrayId, $index, false );

	// make sure at least empty array exists but don't overwrite data
	// we still need in case new array ID same as target array ID
	$array = $store->getArray( $arrayId );
	$store->setArray( $arrayId_new );

	if ( $array === null || !$validIndex ) {
		return '';
	}

	// non-numeric limit will be set to 0, except limit was omitted ('')
	$limit = $limit === '' ? -1 : (int)$limit;
	if ( $limit === 0 ) {
		return '';
	}

	$newArr = [];

	$regexFunSupport = self::hasRegexFunSupport();
	if ( !self::isValidRegEx( $needle, $regexFunSupport ) ) {
		$needle = '/^\s*(' . preg_quote( $needle, '/' ) . ')\s*$/';
	}

	// search the array for all matches and put them in the new array
	$total = count( $array );
	for ( $i = $index; $i < $total; $i++ ) {

		$value = $array[ $i ];

		if ( preg_match( $needle, $value ) ) {
			// Found something!
			if ( $rawTransform !== null ) {
				// Transform the matching string. Can we use 'Regex Fun' with special 'e' flag support ?
				if ( $regexFunSupport ) {
					// do the transformation with Regex Fun to support 'e' flag:
					$transform = trim( $frame->expand(
							$rawTransform,
							PPFrame::NO_ARGS | PPFrame::NO_TEMPLATES // leave expanding of templates to 'Regex Fun'
					) );
					$value = ExtRegexFun::doPregReplace(
							$needle,
							$rawTransform,
							$value,
							-1,
							$parser,
							$frame,
							[ ExtRegexFun::FLAG_REPLACEMENT_PARSE ]
					);
				} else {
					// regular preg_replace:
					$transform = trim( $frame->expand( $rawTransform ) );
					$value = preg_replace( $needle, $transform, $value );
				}
			}
			$newArr[] = trim( $value );

			// stop if limit is reached, limit -1 means no limit
			if ( --$limit === 0 ) {
				break;
			}
		}
	}

	// set new array:
	$store->setArray( $arrayId_new, $newArr );
	return '';
}

处理流程:

  1. 参数解析:提取参数;检查原数组是否存在,验证起始索引有效性(支持负索引),初始化新数组
  2. 搜索条件处理:若非有效正则表达式,自动转换为精确匹配模式 /^\s*(搜索内容)\s*$/
  3. 限制数量处理:空值或非数字转为 -1(不限制),0 则直接返回空数组
  4. 遍历筛选:从起始索引开始,对每个元素用 preg_match 匹配
  5. 转换处理:若匹配成功且设置了转换规则,使用 preg_replace 替换(支持 $0$1 等引用)
  6. 结果清理:对转换后的值执行 trim 操作
  7. 计数控制:每匹配一项递减计数器,达到限制数量时停止
  8. 存储结果:将筛选后的数组存入新数组名,覆盖同名数组

实际用例

一些Wiki使用了相关特性,如下所示这个静态列表可能在下列页面更改后过时仅供批判性参考