函数文档

wptexturize_primes()

💡 云策文档标注

概述

wptexturize_primes() 是 WordPress 核心函数,用于在文本中智能替换引号和撇号(如英尺符号)。它通过逻辑树判断类似“7′.”的字符序列是否代表英尺,并相应转换为 prime 字符或闭合引号字符。

关键要点

  • 函数接收五个参数:$haystack(待搜索文本)、$needle(搜索字符如 ' 或 ")、$prime(prime 字符替换值)、$open_quote(已处理的开放引号字符)、$close_quote(闭合引号字符替换值)。
  • 返回处理后的 $haystack 字符串,完成引号和 prime 的替换。
  • 内部使用正则表达式(如 $quote_pattern 和 $prime_pattern)和逻辑分支(如 Vulcan 逻辑)处理多引号场景。
  • 函数在 wptexturize() 中被调用,用于文本格式化,自 WordPress 4.3.0 版本引入。

代码示例

function wptexturize_primes( $haystack, $needle, $prime, $open_quote, $close_quote ) {
    $spaces           = wp_spaces_regexp();
    $flag             = '';
    $quote_pattern    = "/$needle(?=\Z|[.,:;!?)}\-\]]|>|" . $spaces . ')/';
    $prime_pattern    = "/(?<=\d)$needle(?=\d)/";
    $flag_after_digit = "/(?<=\d)$flag/";
    $flag_no_digit    = "/(?<!\d)$flag/";

    $sentences = explode( $open_quote, $haystack );
    foreach ( $sentences as $key => &$sentence ) {
        if ( ! str_contains( $sentence, $needle ) ) {
            continue;
        } elseif ( 0 !== $key && 0 === substr_count( $sentence, $close_quote ) ) {
            $sentence = preg_replace( $quote_pattern, $flag, $sentence, -1, $count );
            if ( $count > 1 ) {
                // 处理多闭合引号候选的逻辑
                $sentence = preg_replace( $flag_no_digit, $close_quote, $sentence, -1, $count2 );
                if ( 0 === $count2 ) {
                    $count2 = substr_count( $sentence, "$flag." );
                    if ( $count2 > 0 ) {
                        $pos = strrpos( $sentence, "$flag." );
                    } else {
                        $pos = strrpos( $sentence, $flag );
                    }
                    $sentence = substr_replace( $sentence, $close_quote, $pos, strlen( $flag ) );
                }
                $sentence = preg_replace( $prime_pattern, $prime, $sentence );
                $sentence = preg_replace( $flag_after_digit, $prime, $sentence );
                $sentence = str_replace( $flag, $close_quote, $sentence );
            } elseif ( 1 === $count ) {
                $sentence = str_replace( $flag, $close_quote, $sentence );
                $sentence = preg_replace( $prime_pattern, $prime, $sentence );
            } else {
                $sentence = preg_replace( $prime_pattern, $prime, $sentence );
            }
        } else {
            $sentence = preg_replace( $prime_pattern, $prime, $sentence );
            $sentence = preg_replace( $quote_pattern, $close_quote, $sentence );
        }
        if ( '"' === $needle && str_contains( $sentence, '"' ) ) {
            $sentence = str_replace( '"', $close_quote, $sentence );
        }
    }

    return implode( $open_quote, $sentences );
}

注意事项

  • 函数假设开放引号替换已完成(通过 $open_quote 参数),仅处理闭合引号和 prime 字符。
  • 在复杂文本中(如多引号情况),可能依赖启发式逻辑(如 Vulcan 逻辑),可能不总是完美处理所有边缘案例。
  • 与 wp_spaces_regexp() 和 wptexturize() 紧密相关,用于整体文本格式化流程。

📄 原文内容

Implements a logic tree to determine whether or not “7′.” represents seven feet, then converts the special char into either a prime char or a closing quote char.

Parameters

$haystackstringrequired
The plain text to be searched.
$needlestringrequired
The character to search for such as ‘ or “.
$primestringrequired
The prime char to use for replacement.
$open_quotestringrequired
The opening quote char. Opening quote replacement must be accomplished already.
$close_quotestringrequired
The closing quote char to use for replacement.

Return

string The $haystack value after primes and quotes replacements.

Source

function wptexturize_primes( $haystack, $needle, $prime, $open_quote, $close_quote ) {
	$spaces           = wp_spaces_regexp();
	$flag             = '<!--wp-prime-or-quote-->';
	$quote_pattern    = "/$needle(?=\Z|[.,:;!?)}\-\]]|>|" . $spaces . ')/';
	$prime_pattern    = "/(?<=\d)$needle/";
	$flag_after_digit = "/(?<=\d)$flag/";
	$flag_no_digit    = "/(?<!--\d)$flag/";

	$sentences = explode( $open_quote, $haystack );

	foreach ( $sentences as $key =--> &$sentence ) {
		if ( ! str_contains( $sentence, $needle ) ) {
			continue;
		} elseif ( 0 !== $key && 0 === substr_count( $sentence, $close_quote ) ) {
			$sentence = preg_replace( $quote_pattern, $flag, $sentence, -1, $count );
			if ( $count > 1 ) {
				// This sentence appears to have multiple closing quotes. Attempt Vulcan logic.
				$sentence = preg_replace( $flag_no_digit, $close_quote, $sentence, -1, $count2 );
				if ( 0 === $count2 ) {
					// Try looking for a quote followed by a period.
					$count2 = substr_count( $sentence, "$flag." );
					if ( $count2 > 0 ) {
						// Assume the rightmost quote-period match is the end of quotation.
						$pos = strrpos( $sentence, "$flag." );
					} else {
						/*
						 * When all else fails, make the rightmost candidate a closing quote.
						 * This is most likely to be problematic in the context of bug #18549.
						 */
						$pos = strrpos( $sentence, $flag );
					}
					$sentence = substr_replace( $sentence, $close_quote, $pos, strlen( $flag ) );
				}
				// Use conventional replacement on any remaining primes and quotes.
				$sentence = preg_replace( $prime_pattern, $prime, $sentence );
				$sentence = preg_replace( $flag_after_digit, $prime, $sentence );
				$sentence = str_replace( $flag, $close_quote, $sentence );
			} elseif ( 1 === $count ) {
				// Found only one closing quote candidate, so give it priority over primes.
				$sentence = str_replace( $flag, $close_quote, $sentence );
				$sentence = preg_replace( $prime_pattern, $prime, $sentence );
			} else {
				// No closing quotes found. Just run primes pattern.
				$sentence = preg_replace( $prime_pattern, $prime, $sentence );
			}
		} else {
			$sentence = preg_replace( $prime_pattern, $prime, $sentence );
			$sentence = preg_replace( $quote_pattern, $close_quote, $sentence );
		}
		if ( '"' === $needle && str_contains( $sentence, '"' ) ) {
			$sentence = str_replace( '"', $close_quote, $sentence );
		}
	}

	return implode( $open_quote, $sentences );
}

Changelog

Version Description
4.3.0 Introduced.