|
|
@@ -9758,47 +9758,42 @@ Q版卡通风格,头大身小,造型圆润可爱,线条简单,色彩明
|
|
|
Utils::throwError('20003:无法解析生成的分段剧本,请检查格式');
|
|
|
}
|
|
|
|
|
|
- // 获取角色和场景名称用于标记
|
|
|
- $role_names = [];
|
|
|
- $scene_names = [];
|
|
|
+ // 收集所有资产名称(角色、场景、道具)
|
|
|
+ $product_names = [];
|
|
|
|
|
|
+ // 收集角色名称
|
|
|
if (!empty($roles) && is_array($roles)) {
|
|
|
foreach ($roles as $role) {
|
|
|
$role_name = getProp($role, 'role', '');
|
|
|
if (!empty($role_name)) {
|
|
|
- $role_names[] = $role_name;
|
|
|
+ $product_names[] = $role_name;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ // 收集场景名称
|
|
|
if (!empty($scenes) && is_array($scenes)) {
|
|
|
foreach ($scenes as $scene) {
|
|
|
$scene_name = getProp($scene, 'scene', '');
|
|
|
if (!empty($scene_name)) {
|
|
|
- $scene_names[] = $scene_name;
|
|
|
+ $product_names[] = $scene_name;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- // 获取道具名称用于标记
|
|
|
- $prop_names = [];
|
|
|
+ // 收集道具名称
|
|
|
if (!empty($props) && is_array($props)) {
|
|
|
foreach ($props as $prop) {
|
|
|
$prop_name = getProp($prop, 'prop', '');
|
|
|
if (!empty($prop_name)) {
|
|
|
- $prop_names[] = $prop_name;
|
|
|
+ $product_names[] = $prop_name;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- // 对角色、场景、道具名称按长度降序排序(避免短名称先匹配到长名称的一部分)
|
|
|
- usort($role_names, function($a, $b) {
|
|
|
- return mb_strlen($b) - mb_strlen($a);
|
|
|
- });
|
|
|
- usort($scene_names, function($a, $b) {
|
|
|
- return mb_strlen($b) - mb_strlen($a);
|
|
|
- });
|
|
|
- usort($prop_names, function($a, $b) {
|
|
|
+ // 去重并按长度降序排序(避免短名称先匹配到长名称的一部分)
|
|
|
+ $product_names = array_unique($product_names);
|
|
|
+ usort($product_names, function($a, $b) {
|
|
|
return mb_strlen($b) - mb_strlen($a);
|
|
|
});
|
|
|
|
|
|
@@ -9812,142 +9807,32 @@ Q版卡通风格,头大身小,造型圆润可爱,线条简单,色彩明
|
|
|
|
|
|
$processed_content = $act_content;
|
|
|
|
|
|
- // 先匹配场景(在"场景:"后面)
|
|
|
- foreach ($scene_names as $scene_name) {
|
|
|
- // 转义特殊字符
|
|
|
- $escaped_scene = preg_quote($scene_name, '/');
|
|
|
- // 匹配场景:后面的场景名称(可能换行,也可能不换行)
|
|
|
- $pattern = '/(场景:[\s\r\n]*)(' . $escaped_scene . ')/u';
|
|
|
-
|
|
|
- $processed_content = preg_replace_callback($pattern, function($matches) {
|
|
|
- $prefix = $matches[1];
|
|
|
- $scene_name = $matches[2];
|
|
|
-
|
|
|
- // 检查是否已经被标记
|
|
|
- if (strpos($scene_name, '{') === false && strpos($scene_name, '}') === false) {
|
|
|
- return $prefix . '{' . $scene_name . '}';
|
|
|
- }
|
|
|
- return $matches[0];
|
|
|
- }, $processed_content);
|
|
|
- }
|
|
|
-
|
|
|
- // 匹配道具(在"道具:"后面,逻辑与场景一致)
|
|
|
- foreach ($prop_names as $prop_name) {
|
|
|
- // 转义特殊字符
|
|
|
- $escaped_prop = preg_quote($prop_name, '/');
|
|
|
- // 匹配道具:后面的道具名称(可能换行,也可能不换行)
|
|
|
- $pattern = '/(道具:[\s\r\n]*)(' . $escaped_prop . ')/u';
|
|
|
-
|
|
|
- $processed_content = preg_replace_callback($pattern, function($matches) {
|
|
|
- $full_match = $matches[0];
|
|
|
- $prefix = $matches[1];
|
|
|
- $prop_name = $matches[2];
|
|
|
-
|
|
|
- // 检查是否已经被标记
|
|
|
- if (strpos($prop_name, '{') === false && strpos($prop_name, '}') === false) {
|
|
|
- return $prefix . '{' . $prop_name . '}';
|
|
|
- }
|
|
|
- return $full_match;
|
|
|
- }, $processed_content);
|
|
|
- }
|
|
|
-
|
|
|
- // 再匹配角色名称(在"画面:"部分和"角色:"部分)
|
|
|
- foreach ($role_names as $role_name) {
|
|
|
- // 转义特殊字符
|
|
|
- $escaped_role = preg_quote($role_name, '/');
|
|
|
-
|
|
|
- // 1. 匹配"画面:"开始到换行之前的内容
|
|
|
- $pattern = '/(画面:[^\n]*)/u';
|
|
|
- $processed_content = preg_replace_callback($pattern, function($matches) use ($escaped_role) {
|
|
|
- $line = $matches[1]; // 整行"画面:xxxxx"
|
|
|
-
|
|
|
- // 在这一行中匹配所有角色名(避免重复标记)
|
|
|
- $new_line = preg_replace(
|
|
|
- '/(?<![{])(' . $escaped_role . ')(?![}])/u',
|
|
|
- '{$1}',
|
|
|
- $line
|
|
|
- );
|
|
|
-
|
|
|
- return $new_line;
|
|
|
- }, $processed_content);
|
|
|
-
|
|
|
- // 2. 匹配"角色:"或"出场角色:"这一整行内的角色名称
|
|
|
- $pattern = '/((?:出场)?角色:[^\n]*)/u';
|
|
|
- $processed_content = preg_replace_callback($pattern, function($matches) use ($escaped_role) {
|
|
|
- $line = $matches[1]; // 整行"角色:xxxxx"或"出场角色:xxxxx"
|
|
|
-
|
|
|
- // 在这一行中匹配所有角色名(避免重复标记)
|
|
|
- $new_line = preg_replace(
|
|
|
- '/(?<![{])(' . $escaped_role . ')(?![}])/u',
|
|
|
- '{$1}',
|
|
|
- $line
|
|
|
- );
|
|
|
-
|
|
|
- return $new_line;
|
|
|
- }, $processed_content);
|
|
|
- }
|
|
|
-
|
|
|
- // 匹配道具名称(在"画面:"部分,逻辑与角色一致)
|
|
|
- foreach ($prop_names as $prop_name) {
|
|
|
- // 转义特殊字符
|
|
|
- $escaped_prop = preg_quote($prop_name, '/');
|
|
|
-
|
|
|
- // 匹配"画面:"开始到换行之前的内容
|
|
|
- $pattern = '/(画面:[^\n]*)/u';
|
|
|
- $processed_content = preg_replace_callback($pattern, function($matches) use ($escaped_prop) {
|
|
|
- $line = $matches[1]; // 整行"画面:xxxxx"
|
|
|
-
|
|
|
- // 在这一行中匹配所有道具名(避免重复标记)
|
|
|
- $new_line = preg_replace(
|
|
|
- '/(?<![{])(' . $escaped_prop . ')(?![}])/u',
|
|
|
- '{$1}',
|
|
|
- $line
|
|
|
- );
|
|
|
-
|
|
|
- return $new_line;
|
|
|
- }, $processed_content);
|
|
|
- }
|
|
|
+ // 统一替换所有资产名称为 {资产名} 格式
|
|
|
+ // 使用占位符避免嵌套替换问题
|
|
|
+ $placeholder_map = [];
|
|
|
+ $placeholder_index = 0;
|
|
|
|
|
|
- // 匹配角色名称(在"运镜:"部分)
|
|
|
- foreach ($role_names as $role_name) {
|
|
|
+ foreach ($product_names as $product_name) {
|
|
|
// 转义特殊字符
|
|
|
- $escaped_role = preg_quote($role_name, '/');
|
|
|
+ $escaped_product = preg_quote($product_name, '/');
|
|
|
|
|
|
- // 匹配"运镜:"开始到换行之前的内容
|
|
|
- $pattern = '/(运镜:[^\n]*)/u';
|
|
|
- $processed_content = preg_replace_callback($pattern, function($matches) use ($escaped_role) {
|
|
|
- $line = $matches[1]; // 整行"运镜:xxxxx"
|
|
|
-
|
|
|
- // 在这一行中匹配所有角色名(避免重复标记)
|
|
|
- $new_line = preg_replace(
|
|
|
- '/(?<![{])(' . $escaped_role . ')(?![}])/u',
|
|
|
- '{$1}',
|
|
|
- $line
|
|
|
- );
|
|
|
-
|
|
|
- return $new_line;
|
|
|
- }, $processed_content);
|
|
|
- }
|
|
|
-
|
|
|
- // 匹配道具名称(在"运镜:"部分)
|
|
|
- foreach ($prop_names as $prop_name) {
|
|
|
- // 转义特殊字符
|
|
|
- $escaped_prop = preg_quote($prop_name, '/');
|
|
|
-
|
|
|
- // 匹配"运镜:"开始到换行之前的内容
|
|
|
- $pattern = '/(运镜:[^\n]*)/u';
|
|
|
- $processed_content = preg_replace_callback($pattern, function($matches) use ($escaped_prop) {
|
|
|
- $line = $matches[1]; // 整行"运镜:xxxxx"
|
|
|
-
|
|
|
- // 在这一行中匹配所有道具名(避免重复标记)
|
|
|
- $new_line = preg_replace(
|
|
|
- '/(?<![{])(' . $escaped_prop . ')(?![}])/u',
|
|
|
- '{$1}',
|
|
|
- $line
|
|
|
- );
|
|
|
-
|
|
|
- return $new_line;
|
|
|
- }, $processed_content);
|
|
|
+ // 检查是否匹配且未被 {} 包裹
|
|
|
+ $processed_content = preg_replace_callback(
|
|
|
+ '/(?<![{])(' . $escaped_product . ')(?![}])/u',
|
|
|
+ function($matches) use (&$placeholder_map, &$placeholder_index) {
|
|
|
+ // 使用唯一占位符
|
|
|
+ $placeholder = '<<<PLACEHOLDER_' . $placeholder_index . '>>>';
|
|
|
+ $placeholder_map[$placeholder] = '{' . $matches[1] . '}';
|
|
|
+ $placeholder_index++;
|
|
|
+ return $placeholder;
|
|
|
+ },
|
|
|
+ $processed_content
|
|
|
+ );
|
|
|
+ }
|
|
|
+
|
|
|
+ // 将所有占位符替换回实际内容
|
|
|
+ foreach ($placeholder_map as $placeholder => $replacement) {
|
|
|
+ $processed_content = str_replace($placeholder, $replacement, $processed_content);
|
|
|
}
|
|
|
|
|
|
// 处理【镜头X】或【分镜X】重新编号为从1开始的连续整数【镜头X】
|