# 怎么用Python提取字符串中的數字
## 目錄
1. [引言](#引言)
2. [基礎方法](#基礎方法)
- [2.1 使用isdigit()方法](#21-使用isdigit方法)
- [2.2 遍歷字符串](#22-遍歷字符串)
3. [正則表達式方法](#正則表達式方法)
- [3.1 re.findall()基礎用法](#31-refindall基礎用法)
- [3.2 匹配不同數字格式](#32-匹配不同數字格式)
4. [處理復雜場景](#處理復雜場景)
- [4.1 帶符號的數字](#41-帶符號的數字)
- [4.2 科學計數法](#42-科學計數法)
- [4.3 數字與單位組合](#43-數字與單位組合)
5. [性能優化](#性能優化)
- [5.1 編譯正則表達式](#51-編譯正則表達式)
- [5.2 方法選擇建議](#52-方法選擇建議)
6. [實戰案例](#實戰案例)
- [6.1 日志文件分析](#61-日志文件分析)
- [6.2 網頁數據抓取](#62-網頁數據抓取)
7. [常見問題](#常見問題)
8. [總結](#總結)
## 引言
在數據處理和文本分析中,從字符串中提取數字是一項常見但關鍵的任務。Python作為數據處理的首選語言,提供了多種高效的方法來完成這項工作。本文將全面介紹Python中提取字符串數字的各類方法,包括基礎字符串操作、正則表達式高級技巧以及處理特殊場景的解決方案。
## 基礎方法
### 2.1 使用isdigit()方法
`isdigit()`是字符串對象的內置方法,用于檢測字符串是否只包含數字字符(0-9):
```python
text = "訂單12345金額678元"
digits = [char for char in text if char.isdigit()]
result = ''.join(digits)
print(result) # 輸出: 12345678
注意事項: - 只能識別0-9的數字字符 - 無法識別負數符號、小數點等特殊字符 - 對于全角數字(如”123”)會返回False
手動遍歷字符串是最基礎的方法,適合簡單場景:
text = "溫度25.6℃ 濕度70%"
numbers = []
current_num = ""
for char in text:
if char.isdigit() or char == '.':
current_num += char
elif current_num:
numbers.append(float(current_num))
current_num = ""
# 處理最后可能存在的數字
if current_num:
numbers.append(float(current_num))
print(numbers) # 輸出: [25.6, 70]
適用場景: - 數字格式簡單且統一 - 不需要處理復雜符號 - 對性能要求不高的小規模數據處理
正則表達式是處理復雜模式匹配的利器:
import re
text = "服務器內存使用率85%,CPU負載2.5"
numbers = re.findall(r'\d+\.?\d*', text)
print(numbers) # 輸出: ['85', '2.5']
模式說明:
- \d+ 匹配1個或多個數字
- \.? 匹配0或1個小數點
- \d* 匹配0個或多個數字
擴展正則表達式以處理更多數字格式:
text = "收入:+123.45元 支出:-78.90 USD 科學計數:1.23e-4"
pattern = r'[-+]?\d*\.?\d+(?:[eE][-+]?\d+)?'
numbers = re.findall(pattern, text)
print(numbers) # 輸出: ['+123.45', '-78.90', '1.23e-4']
模式解析:
- [-+]? 可選的正負號
- \d*\.?\d+ 整數或小數部分
- (?:[eE][-+]?\d+)? 可選的科學計數法部分
處理包含貨幣符號、千位分隔符的數字:
text = "價格: $1,234.56 ¥789.00"
pattern = r'[$¥]?[,\d]+\.?\d+'
numbers = re.findall(pattern, text)
cleaned = [num.replace('$', '').replace('¥', '').replace(',', '')
for num in numbers]
print(cleaned) # 輸出: ['1234.56', '789.00']
精確匹配科學計數法表示的數字:
text = "常量: 6.022e23 1.6E-19"
pattern = r'[-+]?\d*\.?\d+(?:[eE][-+]?\d+)'
numbers = re.findall(pattern, text)
print(numbers) # 輸出: ['6.022e23', '1.6E-19']
提取帶單位的數字并保留關聯:
text = "距離: 5km 重量: 2.5kg"
pattern = r'(\d+\.?\d*)\s*([a-zA-Z]+)'
matches = re.findall(pattern, text)
print(matches) # 輸出: [('5', 'km'), ('2.5', 'kg')]
對于需要重復使用的模式,預編譯可提升性能:
import re
texts = ["數據1: 123", "數據2: 456", ...] * 1000
pattern = re.compile(r'\d+')
# 單次編譯多次使用
for text in texts:
numbers = pattern.findall(text)
性能對比: - 編譯后速度可提升2-5倍 - 在循環處理大量文本時效果顯著
| 場景 | 推薦方法 | 時間復雜度 |
|---|---|---|
| 簡單數字提取 | isdigit() | O(n) |
| 固定格式數字 | 字符串方法 | O(n) |
| 復雜模式匹配 | 正則表達式 | O(n) |
| 超大規模數據 | 編譯后的正則 | O(n) |
處理服務器日志中的狀態碼和響應時間:
log = """
[2023-01-01 12:00:00] GET /api 200 345ms
[2023-01-01 12:00:01] POST /login 404 210ms
"""
# 提取狀態碼和響應時間(毫秒)
pattern = r'\b(\d{3})\s(\d+)ms'
matches = re.findall(pattern, log)
for status, time in matches:
print(f"狀態碼: {status}, 響應時間: {time}ms")
從HTML中提取產品價格信息:
html = """
<div class="price">¥1,299.00</div>
<span class="discount">8.5折</span>
"""
# 提取價格和折扣
price = re.search(r'¥([\d,]+\.\d{2})', html).group(1)
discount = re.search(r'(\d\.\d)折', html).group(1)
print(f"價格: {price.replace(',', '')}, 折扣: {float(discount)*10}%")
Q1: 如何區分數字編號和真正需要計算的數值? A: 結合上下文判斷,或使用更精確的正則模式,例如:
# 只匹配特定格式的數值
pattern = r'\b\d+\.\d{2}\b' # 匹配xx.xx格式的價格
Q2: 處理混合編碼文本時數字提取失??? A: 先統一編碼:
text = "數據:123".encode('utf-8').decode('unicode-escape')
Q3: 超大文本內存不足怎么辦? A: 使用流式處理:
with open('large_file.txt') as f:
for line in f:
numbers = re.findall(pattern, line)
process(numbers)
Python提供了從簡單到復雜的多種數字提取方案:
1. 對于簡單需求,isdigit()和基本字符串操作足夠高效
2. 正則表達式是處理復雜模式的終極武器
3. 性能關鍵場景應考慮預編譯正則表達式
4. 特殊格式需要定制化解決方案
選擇合適的方法需要綜合考慮:數據規模、數字格式復雜度、性能要求和開發效率。掌握這些技術后,你將能輕松應對各類文本數據中的數字提取需求。
擴展學習: - 官方re模塊文檔:https://docs.python.org/3/library/re.html - 正則表達式可視化工具:https://regex101.com/ - Pandas文本處理:pd.Series.str.extract() “`
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。