我想构建一个检测所有特殊字符并在其周围添加空格的规范化工具。
问题是有不同形状的数据,我需要保持原样,如:邮件,日期,小时,十进制数字(42.11)和链接。
我构建了用于十进制数字,主题标签,小时和邮件(我不确定邮件)的内容:例如,在主题标签中,tokeniser检测到所有#
在文本中,除了标签形式为#test
的那个。
在每种情况下,我都试图构建一个针对每种情况的反面的正则表达式。
下面是带有正则表达式的代码示例:
def clean_str(string):
string = re.sub(r"((?<=\D)\.(?=\D)?|(?<=\D)?\.(?=\D))", " . ", string) #. numbers 44.55
string = re.sub(r"((?<=\D)\:(?=\D)?|(?<=\D)?\:(?=\D))", " . ", string) #. Hours
string = re.sub(r"((?<!\s)(@|#)|(@|#)(?=[^a-zA-Z]))", " . ", string) #. Hashtags
string = re.sub(r"((?<=[^a-zA-Z])?@(?=[^a-zA-Z])[^.]?|(?<=[^a-zA-Z])@(?=[^a-zA-Z])?[^.])", " . ", string) #. mails
string = re.sub(r"[^A-Za-z0-9]", " , ", string) #, all speciall characters
return string.strip().lower()
问题是,如果我想构建一个适用于邮件的邮箱,则会考虑多个相反的情况test@test.com
。
例如:
test@.com
@.
@test.com
.
.
在十进制数的正则表达式脚本中,由于只有两个方面可以检查LEFTSIDE.RIGHTSIDE
,所以更容易。
那么为链接,邮件等构建这样的正则表达式脚本的正确方法是什么?
我错过了什么吗?
-----编辑
为了让我的问题更清楚,如果我有这个输入文字:
"I will to! then we# are test@test.com but .not so."
输出应该是这样的:
I
want
to
!
then
we
#
are
test@test.com
but
.
not
so
.
答案 0 :(得分:1)
基本上你想要构建的是一个解析器,它可能无法通过RegEx完成(可能可能,但它通过解析器更有效)。在这种情况下,您将运行词法分析器来扫描源代码并将您的词汇转换为令牌。这可以像几个类别一样简单:
然后,您将遍历每个令牌以检查是否可以通过语法分析将其解析为所需的格式。因为您所需的语法非常简单,所以可以使用递归下降解析器。我不知道你想对数据做什么(除了验证它),但通常在语法分析阶段你会构建一个解析或语法树。我多年没有使用过Python,但是语法分析阶段的一些伪代码将是:
function parseNumber(source, index) {
if source.subString(index).startsWith(digits) {
index += number.Length
if source.subString(index).startsWith(decimal_place) {
index += decimal_place.Length
if source.subString(index).startsWith(digits) {
index += number.Length
} else {
index -= decimal_place.Length
}
}
return True
}
return False
}