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.
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. |