参考文献格式--book

This commit is contained in:
wangjinlei
2026-08-07 16:04:59 +08:00
parent 175d2edc55
commit a1e151048c
3 changed files with 475 additions and 92 deletions

View File

@@ -120,29 +120,23 @@ class BookMetadataService
return $hints;
}
// 章节引用In: 编者. 书名. ...)反查的是书,不是章节
$bookPart = $content;
if (preg_match('/\bIn:\s*(.+)$/i', $content, $m)) {
$bookPart = trim($m[1]);
$hints['title'] = '';
// 反查用规则解析即可,不为了取个 ISBN 再多花一次大模型调用
$parsed = (new BookCitationParser(['use_llm' => false]))->parse($content);
// 章节引用反查的是书,不是章节
if ($parsed['container'] !== '') {
$hints['title'] = $parsed['container'];
} elseif ($hints['title'] === '') {
$hints['title'] = $parsed['title'];
}
$hints['edition'] = $this->parseEdition($content);
if ($hints['year'] === '' && preg_match_all('/\b(?:19|20)\d{2}\b/', $content, $ym)) {
$hints['year'] = end($ym[0]);
foreach (['author', 'publisher', 'edition'] as $field) {
if ($hints[$field] === '' && $parsed[$field] !== '') {
$hints[$field] = $parsed[$field];
}
}
// 地点: 出版社; 年份
if ($hints['publisher'] === '' && preg_match('/:\s*([^;:]{2,60}?)\s*[;,]\s*(?:19|20)\d{2}/u', $bookPart, $m)) {
$hints['publisher'] = trim($m[1], " .,");
}
if ($hints['title'] === '') {
$hints['title'] = $this->parseTitle($bookPart);
}
if ($hints['author'] === '') {
$hints['author'] = $this->parseAuthor($bookPart);
if ($hints['year'] === '') {
$hints['year'] = $parsed['year'];
}
return $hints;
@@ -432,38 +426,6 @@ class BookMetadataService
return trim($title, " .,;:");
}
private function parseTitle($text)
{
$parts = preg_split('/\.\s+/u', trim((string)$text), 3);
if (is_array($parts) && count($parts) >= 2) {
return $this->cleanTitle($parts[1]);
}
return '';
}
private function parseAuthor($text)
{
$parts = preg_split('/\.\s+/u', trim((string)$text), 2);
return is_array($parts) && count($parts) >= 2 ? trim($parts[0]) : '';
}
private function parseEdition($text)
{
if (preg_match('/\b(\d{1,2})\s*(?:st|nd|rd|th|d)?\s*(?:ed\.?|edition)\b/iu', $text, $m)) {
return $m[1];
}
if (preg_match('/\b(first|second|third|fourth|fifth|sixth|seventh|eighth|ninth|tenth)\s+(?:ed\.?|edition)\b/iu', $text, $m)) {
return $m[1];
}
if (preg_match('/第\s*(\d{1,2})\s*版/u', $text, $m)) {
return $m[1];
}
return '';
}
private function editionOrdinal($edition)
{
$edition = strtolower(trim((string)$edition));