forked from actlaboratory/falcon
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathStringUtil.py
84 lines (74 loc) · 2.2 KB
/
StringUtil.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
# -*- coding: utf-8 -*-
#Falcon String Utility
#Copyright (C) 2020 yamahubuki <itiro.ishino@gmail.com>
#Note: All comments except these top lines will be written in Japanese.
#UTF-8のバイト列bのインデックスiの位置から始まる文字の(バイト数,幅)を返す
#幅はASCIIと半角カタカナだけ1、他は2を返す
def _GetWidth(b,i):
c=b[i]
#cを基に、その文字のバイト数を求める
if c<0x80:clen=1
elif c<0xE0:clen=2
elif c<0xF0:clen=3
else: clen=4
#その文字の幅を求める
if clen==1:
width=1
elif clen==3:
if b[i] == 0xEF and b[i+1] >= 0xBC and b[i+2] >= 0x80:
width=1
else:
width=2
else:
width=2
return clen,width
def GetLimitedString(s,l):
"""
文字列sの先頭から、半角l文字分の幅まで取得
収まらない場合、末尾に「...」が入り、この「...」の長さもlに含む
"""
l=int(l)
bytes=bytearray(s.encode())
resultCount=0 #カーソル直前までの文字幅合計(半角でカウント)
cursor=0 #カーソル位置
while(resultCount<=l-3 and cursor<len(bytes)):
clen,width=_GetWidth(bytes,cursor)
if resultCount+width<=l-3: #カーソルを進め、resultCountを加算
cursor+=clen
resultCount+=width
else: #文字数オーバーする
break
#残りの文字が半角3文字以内ならそのままでよい
exCount=0
exCursor=cursor
while(exCount+resultCount<=l and exCursor+cursor<len(bytes)):
clen,width=_GetWidth(bytes,cursor+exCursor)
if exCount+width+resultCount<=l: #カーソルを進め、resultCountを加算
exCursor+=clen
exCount+=width
else: #文字数オーバーする
break
if exCursor==len(bytes):
return s #入力のまま
#"..."を入れる
for i in range(3):
bytes[cursor]=46 #.のASCIIコード46
cursor+=1
#cursor以下の文字をカットして返す
while(cursor<len(bytes)):
bytes[cursor]=0
cursor+=1
return bytes.decode()
def GetWidthCount(s):
"""
文字列sの幅を半角=1・全角=2で計算して返す。
計算方法は_GetWidth()に準じる
"""
result=0
cursor=0
bytes=bytearray(s.encode())
while(cursor<len(bytes)):
clen,width=_GetWidth(bytes,cursor)
cursor+=clen
result+=width
return result