社区文档构建进行中,欢迎编辑。社区答疑群(非官方):717421103

全站通知:

帮助:解析函数/arraysearcharray

来自WIKI实验室WIKI_BWIKI_哔哩哔哩
跳到导航 跳到搜索

Arraysearcharray是一个解析函数。帮助:解析函数页列出了所有解析函数的说明。

arraysearcharray

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

创建一个新数组,包括指定数组中所有符合条件的元素。搜索条件支持正则表达式

支持指定搜索起始位置和最大结果数量。当搜索条件是正则时,可以额外指定结果的转换规则。

语法

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

  • 新数组名: 将用于保存筛选结果。
  • 原数组名: 目标数组。
  • 搜索条件: 正则表达式或字符串搜索值。
  • 起始索引: 从目标数组的指定位置开始搜索。
  • 限制数量: 限制返回结果的数量。不限制可以留空或填-1。
  • 转换规则: 可选参数,对搜索结果进行转换,如果搜索值是正则表达式,transform 可以包含 $n,其中 n 是正则表达式结果中的变量。

示例

定义一个数组a为:{{#arraydefine:a|apple, bule1, fly, add1,,,, wiki}} = apple、bule1、fly、add1、、、、wiki

将所有a开头的值存入x {{#arraysearcharray:x|a|/^a.+/ }} -> apple、add1
a开头,从第2项开始 {{#arraysearcharray:x|a|/^a.+/ | 2}} -> add1
a开头,仅限1个 {{#arraysearcharray:x|a|/^a.+/ | 0 | 1}} -> apple
将数字结尾的值存入x {{#arraysearcharray:x|a|/^.*?(\d+)$/}} -> bule1、add1
数字结尾,调整格式 {{#arraysearcharray:x|a|/^.*?(\d+)$/||| '''pre-$0''' }} -> pre-bule1pre-add1
删除空值 {{#arraysearcharray:a|a|/\S+/}} -> apple、bule1、fly、add1、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 '';
}

代码逻辑:

  • 解析参数,包括原数组 ID、新数组 ID、搜索值、起始索引、限制数量和转换规则。
  • 验证索引是否有效,获取原数组,并创建新数组。
  • 对搜索值进行正则表达式验证,如果不是有效的正则表达式,则转换为匹配完整字符串的正则表达式。
  • 遍历原数组,对每个值进行搜索匹配,如果找到匹配项,根据需要进行转换(基于PHP的preg_replace),并将匹配结果存入新数组中,直到达到限制数量或搜索完整个数组。
  • 保存新数组。

实际用例

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