textutils-py 0.1.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- textutils_py-0.1.1/LICENSE +0 -0
- textutils_py-0.1.1/PKG-INFO +32 -0
- textutils_py-0.1.1/README.md +8 -0
- textutils_py-0.1.1/setup.cfg +4 -0
- textutils_py-0.1.1/setup.py +37 -0
- textutils_py-0.1.1/tests/__init__.py +0 -0
- textutils_py-0.1.1/tests/test_core.py +32 -0
- textutils_py-0.1.1/textutils/__init__.py +25 -0
- textutils_py-0.1.1/textutils/core.py +106 -0
- textutils_py-0.1.1/textutils/utils.py +61 -0
- textutils_py-0.1.1/textutils_py.egg-info/PKG-INFO +32 -0
- textutils_py-0.1.1/textutils_py.egg-info/SOURCES.txt +12 -0
- textutils_py-0.1.1/textutils_py.egg-info/dependency_links.txt +1 -0
- textutils_py-0.1.1/textutils_py.egg-info/top_level.txt +2 -0
|
File without changes
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: textutils_py
|
|
3
|
+
Version: 0.1.1
|
|
4
|
+
Summary: 一个功能丰富的文本处理工具集
|
|
5
|
+
Home-page: https://github.com/你的用户名/textutils-py
|
|
6
|
+
Author: 袁培钦
|
|
7
|
+
Author-email: 570686818@qq.com
|
|
8
|
+
Project-URL: Bug Reports, https://github.com/你的用户名/textutils-py/issues
|
|
9
|
+
Project-URL: Source, https://github.com/你的用户名/textutils-py
|
|
10
|
+
Classifier: Programming Language :: Python :: 3
|
|
11
|
+
Classifier: Programming Language :: Python :: 3.7
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.8
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
16
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
17
|
+
Classifier: Operating System :: OS Independent
|
|
18
|
+
Classifier: Development Status :: 4 - Beta
|
|
19
|
+
Classifier: Intended Audience :: Developers
|
|
20
|
+
Classifier: Topic :: Text Processing
|
|
21
|
+
Requires-Python: >=3.7
|
|
22
|
+
Description-Content-Type: text/markdown
|
|
23
|
+
License-File: LICENSE
|
|
24
|
+
|
|
25
|
+
# TextUtils-Py
|
|
26
|
+
|
|
27
|
+
一个功能丰富的文本处理Python工具集。
|
|
28
|
+
|
|
29
|
+
## 安装
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
pip install textutils-py
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
from setuptools import setup, find_packages
|
|
2
|
+
|
|
3
|
+
with open("README.md", "r", encoding="utf-8") as fh:
|
|
4
|
+
long_description = fh.read()
|
|
5
|
+
|
|
6
|
+
setup(
|
|
7
|
+
name="textutils_py", # PyPI上的包名
|
|
8
|
+
version="0.1.1",
|
|
9
|
+
author="袁培钦",
|
|
10
|
+
author_email="570686818@qq.com",
|
|
11
|
+
description="一个功能丰富的文本处理工具集",
|
|
12
|
+
long_description=long_description,
|
|
13
|
+
long_description_content_type="text/markdown",
|
|
14
|
+
url="https://github.com/你的用户名/textutils-py",
|
|
15
|
+
packages=find_packages(),
|
|
16
|
+
classifiers=[
|
|
17
|
+
"Programming Language :: Python :: 3",
|
|
18
|
+
"Programming Language :: Python :: 3.7",
|
|
19
|
+
"Programming Language :: Python :: 3.8",
|
|
20
|
+
"Programming Language :: Python :: 3.9",
|
|
21
|
+
"Programming Language :: Python :: 3.10",
|
|
22
|
+
"Programming Language :: Python :: 3.11",
|
|
23
|
+
"License :: OSI Approved :: MIT License",
|
|
24
|
+
"Operating System :: OS Independent",
|
|
25
|
+
"Development Status :: 4 - Beta",
|
|
26
|
+
"Intended Audience :: Developers",
|
|
27
|
+
"Topic :: Text Processing",
|
|
28
|
+
],
|
|
29
|
+
python_requires=">=3.7",
|
|
30
|
+
install_requires=[
|
|
31
|
+
# 依赖包列表
|
|
32
|
+
],
|
|
33
|
+
project_urls={
|
|
34
|
+
"Bug Reports": "https://github.com/你的用户名/textutils-py/issues",
|
|
35
|
+
"Source": "https://github.com/你的用户名/textutils-py",
|
|
36
|
+
},
|
|
37
|
+
)
|
|
File without changes
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import unittest
|
|
2
|
+
from textutils import TextProcessor
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class TestTextProcessor(unittest.TestCase):
|
|
6
|
+
|
|
7
|
+
def test_reverse(self):
|
|
8
|
+
self.assertEqual(TextProcessor.reverse("hello"), "olleh")
|
|
9
|
+
self.assertEqual(TextProcessor.reverse(""), "")
|
|
10
|
+
|
|
11
|
+
def test_count_words(self):
|
|
12
|
+
self.assertEqual(TextProcessor.count_words("hello world"), 2)
|
|
13
|
+
self.assertEqual(TextProcessor.count_words(""), 0)
|
|
14
|
+
|
|
15
|
+
def test_is_palindrome(self):
|
|
16
|
+
self.assertTrue(TextProcessor.is_palindrome("racecar"))
|
|
17
|
+
self.assertTrue(TextProcessor.is_palindrome("A man a plan a canal Panama"))
|
|
18
|
+
self.assertFalse(TextProcessor.is_palindrome("hello"))
|
|
19
|
+
|
|
20
|
+
def test_extract_emails(self):
|
|
21
|
+
text = "Contact me at test@example.com or support@test.org"
|
|
22
|
+
emails = TextProcessor.extract_emails(text)
|
|
23
|
+
self.assertEqual(len(emails), 2)
|
|
24
|
+
self.assertEqual(emails[0], "test@example.com")
|
|
25
|
+
|
|
26
|
+
def test_to_slug(self):
|
|
27
|
+
self.assertEqual(TextProcessor.to_slug("Hello World!"), "hello-world")
|
|
28
|
+
self.assertEqual(TextProcessor.to_slug("Python 3.9"), "python-39")
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
if __name__ == '__main__':
|
|
32
|
+
unittest.main()
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"""
|
|
2
|
+
textutils - 文本处理工具集
|
|
3
|
+
一个功能丰富的文本处理Python库
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
from textutils.core import TextProcessor
|
|
7
|
+
from textutils.utils import (
|
|
8
|
+
generate_random_string,
|
|
9
|
+
generate_uuid,
|
|
10
|
+
truncate,
|
|
11
|
+
count_occurrences,
|
|
12
|
+
remove_stopwords,
|
|
13
|
+
is_valid_email
|
|
14
|
+
)
|
|
15
|
+
|
|
16
|
+
__version__ = "0.1.1"
|
|
17
|
+
__all__ = [
|
|
18
|
+
'TextProcessor',
|
|
19
|
+
'generate_random_string',
|
|
20
|
+
'generate_uuid',
|
|
21
|
+
'truncate',
|
|
22
|
+
'count_occurrences',
|
|
23
|
+
'remove_stopwords',
|
|
24
|
+
'is_valid_email'
|
|
25
|
+
]
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
"""
|
|
2
|
+
textutils - 文本处理工具集核心模块
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
import re
|
|
6
|
+
import hashlib
|
|
7
|
+
from typing import List, Optional, Union
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class TextProcessor:
|
|
11
|
+
"""文本处理器类"""
|
|
12
|
+
|
|
13
|
+
@staticmethod
|
|
14
|
+
def reverse(text: str) -> str:
|
|
15
|
+
"""反转字符串"""
|
|
16
|
+
return text[::-1]
|
|
17
|
+
|
|
18
|
+
@staticmethod
|
|
19
|
+
def count_words(text: str) -> int:
|
|
20
|
+
"""统计单词数量"""
|
|
21
|
+
return len(text.split())
|
|
22
|
+
|
|
23
|
+
@staticmethod
|
|
24
|
+
def count_chars(text: str, ignore_spaces: bool = False) -> int:
|
|
25
|
+
"""统计字符数量"""
|
|
26
|
+
if ignore_spaces:
|
|
27
|
+
return len(text.replace(" ", ""))
|
|
28
|
+
return len(text)
|
|
29
|
+
|
|
30
|
+
@staticmethod
|
|
31
|
+
def remove_duplicates(text: str) -> str:
|
|
32
|
+
"""去除重复字符"""
|
|
33
|
+
seen = set()
|
|
34
|
+
result = []
|
|
35
|
+
for char in text:
|
|
36
|
+
if char not in seen:
|
|
37
|
+
seen.add(char)
|
|
38
|
+
result.append(char)
|
|
39
|
+
return ''.join(result)
|
|
40
|
+
|
|
41
|
+
@staticmethod
|
|
42
|
+
def extract_emails(text: str) -> List[str]:
|
|
43
|
+
"""提取所有邮箱地址"""
|
|
44
|
+
pattern = r'[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}'
|
|
45
|
+
return re.findall(pattern, text)
|
|
46
|
+
|
|
47
|
+
@staticmethod
|
|
48
|
+
def extract_urls(text: str) -> List[str]:
|
|
49
|
+
"""提取所有URL"""
|
|
50
|
+
pattern = r'https?://[^\s<>"{}|\\^`\[\]]+'
|
|
51
|
+
return re.findall(pattern, text)
|
|
52
|
+
|
|
53
|
+
@staticmethod
|
|
54
|
+
def to_slug(text: str) -> str:
|
|
55
|
+
"""转换为URL友好的slug格式"""
|
|
56
|
+
text = text.lower()
|
|
57
|
+
text = re.sub(r'[^a-z0-9\s-]', '', text)
|
|
58
|
+
text = re.sub(r'[-\s]+', '-', text)
|
|
59
|
+
return text.strip('-')
|
|
60
|
+
|
|
61
|
+
@staticmethod
|
|
62
|
+
def is_palindrome(text: str) -> bool:
|
|
63
|
+
"""判断是否为回文"""
|
|
64
|
+
cleaned = re.sub(r'[^a-zA-Z0-9]', '', text).lower()
|
|
65
|
+
return cleaned == cleaned[::-1]
|
|
66
|
+
|
|
67
|
+
@staticmethod
|
|
68
|
+
def get_hash(text: str, algorithm: str = 'sha256') -> str:
|
|
69
|
+
"""计算文本哈希值"""
|
|
70
|
+
hash_func = hashlib.new(algorithm)
|
|
71
|
+
hash_func.update(text.encode('utf-8'))
|
|
72
|
+
return hash_func.hexdigest()
|
|
73
|
+
|
|
74
|
+
@staticmethod
|
|
75
|
+
def wrap_text(text: str, width: int = 70) -> str:
|
|
76
|
+
"""按指定宽度换行"""
|
|
77
|
+
words = text.split()
|
|
78
|
+
lines = []
|
|
79
|
+
current_line = []
|
|
80
|
+
current_length = 0
|
|
81
|
+
|
|
82
|
+
for word in words:
|
|
83
|
+
if current_length + len(word) + 1 <= width:
|
|
84
|
+
current_line.append(word)
|
|
85
|
+
current_length += len(word) + 1
|
|
86
|
+
else:
|
|
87
|
+
if current_line:
|
|
88
|
+
lines.append(' '.join(current_line))
|
|
89
|
+
current_line = [word]
|
|
90
|
+
current_length = len(word)
|
|
91
|
+
|
|
92
|
+
if current_line:
|
|
93
|
+
lines.append(' '.join(current_line))
|
|
94
|
+
|
|
95
|
+
return '\n'.join(lines)
|
|
96
|
+
|
|
97
|
+
@staticmethod
|
|
98
|
+
def find_most_common(text: str, n: int = 5) -> List[tuple]:
|
|
99
|
+
"""找出最常见的n个单词"""
|
|
100
|
+
words = re.findall(r'\b[a-zA-Z]+\b', text.lower())
|
|
101
|
+
word_count = {}
|
|
102
|
+
for word in words:
|
|
103
|
+
word_count[word] = word_count.get(word, 0) + 1
|
|
104
|
+
|
|
105
|
+
sorted_words = sorted(word_count.items(), key=lambda x: x[1], reverse=True)
|
|
106
|
+
return sorted_words[:n]
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
"""
|
|
2
|
+
textutils - 辅助工具函数
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
import random
|
|
6
|
+
import string
|
|
7
|
+
from typing import List, Optional
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def generate_random_string(length: int = 8,
|
|
11
|
+
include_digits: bool = True,
|
|
12
|
+
include_punctuation: bool = False) -> str:
|
|
13
|
+
"""生成随机字符串"""
|
|
14
|
+
chars = string.ascii_letters
|
|
15
|
+
if include_digits:
|
|
16
|
+
chars += string.digits
|
|
17
|
+
if include_punctuation:
|
|
18
|
+
chars += string.punctuation
|
|
19
|
+
|
|
20
|
+
return ''.join(random.choice(chars) for _ in range(length))
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def generate_uuid(prefix: str = '') -> str:
|
|
24
|
+
"""生成短UUID"""
|
|
25
|
+
import uuid
|
|
26
|
+
uid = str(uuid.uuid4()).replace('-', '')[:12]
|
|
27
|
+
return f"{prefix}{uid}" if prefix else uid
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def truncate(text: str, max_length: int = 100, suffix: str = '...') -> str:
|
|
31
|
+
"""截断文本"""
|
|
32
|
+
if len(text) <= max_length:
|
|
33
|
+
return text
|
|
34
|
+
return text[:max_length - len(suffix)] + suffix
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def count_occurrences(text: str, substring: str, ignore_case: bool = False) -> int:
|
|
38
|
+
"""统计子串出现次数"""
|
|
39
|
+
if ignore_case:
|
|
40
|
+
text = text.lower()
|
|
41
|
+
substring = substring.lower()
|
|
42
|
+
return text.count(substring)
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def remove_stopwords(text: str, stopwords: Optional[List[str]] = None) -> str:
|
|
46
|
+
"""移除停用词"""
|
|
47
|
+
if stopwords is None:
|
|
48
|
+
# 默认英文停用词
|
|
49
|
+
stopwords = ['a', 'an', 'the', 'and', 'or', 'but', 'in', 'on', 'at',
|
|
50
|
+
'to', 'for', 'of', 'with', 'without', 'by']
|
|
51
|
+
|
|
52
|
+
words = text.split()
|
|
53
|
+
filtered = [w for w in words if w.lower() not in stopwords]
|
|
54
|
+
return ' '.join(filtered)
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
def is_valid_email(email: str) -> bool:
|
|
58
|
+
"""验证邮箱格式"""
|
|
59
|
+
import re
|
|
60
|
+
pattern = r'^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$'
|
|
61
|
+
return bool(re.match(pattern, email))
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: textutils-py
|
|
3
|
+
Version: 0.1.1
|
|
4
|
+
Summary: 一个功能丰富的文本处理工具集
|
|
5
|
+
Home-page: https://github.com/你的用户名/textutils-py
|
|
6
|
+
Author: 袁培钦
|
|
7
|
+
Author-email: 570686818@qq.com
|
|
8
|
+
Project-URL: Bug Reports, https://github.com/你的用户名/textutils-py/issues
|
|
9
|
+
Project-URL: Source, https://github.com/你的用户名/textutils-py
|
|
10
|
+
Classifier: Programming Language :: Python :: 3
|
|
11
|
+
Classifier: Programming Language :: Python :: 3.7
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.8
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
16
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
17
|
+
Classifier: Operating System :: OS Independent
|
|
18
|
+
Classifier: Development Status :: 4 - Beta
|
|
19
|
+
Classifier: Intended Audience :: Developers
|
|
20
|
+
Classifier: Topic :: Text Processing
|
|
21
|
+
Requires-Python: >=3.7
|
|
22
|
+
Description-Content-Type: text/markdown
|
|
23
|
+
License-File: LICENSE
|
|
24
|
+
|
|
25
|
+
# TextUtils-Py
|
|
26
|
+
|
|
27
|
+
一个功能丰富的文本处理Python工具集。
|
|
28
|
+
|
|
29
|
+
## 安装
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
pip install textutils-py
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
LICENSE
|
|
2
|
+
README.md
|
|
3
|
+
setup.py
|
|
4
|
+
tests/__init__.py
|
|
5
|
+
tests/test_core.py
|
|
6
|
+
textutils/__init__.py
|
|
7
|
+
textutils/core.py
|
|
8
|
+
textutils/utils.py
|
|
9
|
+
textutils_py.egg-info/PKG-INFO
|
|
10
|
+
textutils_py.egg-info/SOURCES.txt
|
|
11
|
+
textutils_py.egg-info/dependency_links.txt
|
|
12
|
+
textutils_py.egg-info/top_level.txt
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|