1+ import re
2+ from typing import List , Dict
3+
4+ class DailyAIConsultingNews :
5+ def __init__ (self ):
6+ self .title = ""
7+ self .date = ""
8+ self .body = ""
9+ self .items = []
10+
11+ def parse (self ) -> None :
12+ """Parse the body content into structured news items."""
13+ if not self .body :
14+ self .items = []
15+ return
16+
17+ # Split body into lines and strip whitespace
18+ lines = [line .strip () for line in self .body .split ('\n ' )]
19+
20+ # Extract title and date from header
21+ title_line = next ((line for line in lines if line .startswith ('##' )), '' )
22+ if title_line :
23+ self .title = title_line [2 :].strip ()
24+
25+ date_match = re .search (r'\d{4} 年 \d{1,2} 月 \d{1,2} 日' , self .body )
26+ if date_match :
27+ self .date = date_match .group ()
28+
29+ # Find the start of news items (after "## 今日 AI 咨询行业要点")
30+ item_start_idx = - 1
31+ for i , line in enumerate (lines ):
32+ if line .startswith ('## 今日 AI 咨询行业要点' ):
33+ item_start_idx = i + 1
34+ break
35+
36+ if item_start_idx == - 1 :
37+ self .items = []
38+ return
39+
40+ # Collect all lines from item start onward
41+ content_lines = lines [item_start_idx :]
42+ items = []
43+ current_item = None
44+
45+ reference_pattern = re .compile (r'^[-*] 参考:$|^\[参考\]$' )
46+
47+ for line in content_lines :
48+ # Match numbered headlines (### 1., ### 2., etc.)
49+ headline_match = re .match (r'^###\s*\d+\.\s*(.+)$' , line )
50+ if headline_match :
51+ if current_item is not None :
52+ items .append (current_item )
53+ current_item = {
54+ 'id' : len (items ) + 1 ,
55+ 'headline' : headline_match .group (1 ).strip (),
56+ 'summary' : '' ,
57+ 'references' : []
58+ }
59+ continue
60+
61+ if current_item is None :
62+ continue
63+
64+ # Check for reference lines
65+ if re .match (r'^[-*]\s*参考:' , line ) or line .startswith ('Reference:' ):
66+ # Extract URL from markdown link if present
67+ url_match = re .search (r'\[.*?\]\((https?://[^\)]+)\)' , line )
68+ if url_match :
69+ current_item ['references' ].append (url_match .group (1 ))
70+ else :
71+ # Fallback: extract any URL
72+ url_only = re .search (r'(https?://[^\s]+)' , line )
73+ if url_only :
74+ current_item ['references' ].append (url_only .group (1 ))
75+ continue
76+
77+ # Accumulate summary text (skip separators)
78+ if line in ['---' , '--' , '' ]:
79+ continue
80+
81+ # If no current item, skip
82+ if not current_item :
83+ continue
84+
85+ # Add to summary if not a new section
86+ if not line .startswith ('###' ):
87+ if current_item ['summary' ]:
88+ current_item ['summary' ] += ' ' + line
89+ else :
90+ current_item ['summary' ] = line
91+
92+ # Append last item
93+ if current_item is not None :
94+ items .append (current_item )
95+
96+ self .items = items
97+
98+ def get_items (self ) -> List [Dict ]:
99+ """Return parsed news items."""
100+ if not self .items :
101+ self .parse ()
102+ return self .items
103+
104+ def to_dict (self ) -> Dict :
105+ """Convert to dictionary format."""
106+ return {
107+ 'title' : self .title ,
108+ 'date' : self .date ,
109+ 'items' : self .get_items ()
110+ }
0 commit comments