3

我有一个包含单词和数字的文本。我将举一个具有代表性的文本示例:

string = "This is a 1example of the text. But, it only is 2.5 percent of all data"

我想将其转换为:

"This is a  1 example of the text But it only is  2.5  percent of all data"

所以删除标点符号(可以是. ,或任何其他string.punctuation),并在连接时在数字和单词之间放置一个空格。但是在我的例子中保持浮动像 2.5。

我使用了以下代码:

item = "This is a 1example of the text. But, it only is 2.5 percent of all data"
item = ' '.join(re.sub( r"([A-Z])", r" \1", item).split())
# This a start but not there yet !
#item = ' '.join([x.strip(string.punctuation) for x in item.split() if x not in string.digits])
item = ' '.join(re.split(r'(\d+)', item) )
print item

结果是:

 >> "This is a  1 example of the text. But, it only is  2 . 5  percent of all data"

我快到了,但无法弄清楚最后的和平。

4

6 回答 6

7

您可以像这样使用正则表达式外观:

(?<!\d)[.,;:](?!\d)

工作演示

这个想法是让一个字符类收集你想要替换的标点符号,并使用环视来匹配没有数字的标点符号

regex = r"(?<!\d)[.,;:](?!\d)"

test_str = "This is a 1example of the text. But, it only is 2.5 percent of all data"

result = re.sub(regex, "", test_str, 0)

结果是:

This is a 1example of the text But it only is 2.5 percent of all data
于 2017-03-31T14:59:28.747 回答
1

好的,伙计们,这是一个答案(最好的?我不知道,但它似乎有效):

item = "This is a 1example 2Ex of the text.But, it only is 2.5 percent of all data?"
#if there is two strings contatenated with the second starting with capital letter
item = ' '.join(re.sub( r"([A-Z])", r" \1", item).split())
#if a word starts with a digit like "1example"
item = ' '.join(re.split(r'(\d+)([A-Za-z]+)', item) )
#Magical line that removes punctuation apart from floats
item = re.sub('\S+', lambda m: re.match(r'^\W*(.*\w)\W*$', m.group()).group(1), item)
item = item.replace("  "," ")
print item
于 2017-03-31T14:56:15.053 回答
0

代码:

from itertools import groupby

s1 = "This is a 1example of the text. But, it only is 2.5 percent of all data"
s2 = [''.join(g) for _, g in groupby(s1, str.isalpha)]
s3 = ' '.join(s2).replace("   ", "  ").replace("  ", " ")

#you can keep adding a replace for each ponctuation
s4 = s3.replace(". ", " ").replace(", "," ").replace("; "," ").replace(", "," ").replace("- "," ").replace("? "," ").replace("! "," ").replace(" ("," ").replace(") "," ").replace('" '," ").replace(' "'," ").replace('... '," ").replace('/ '," ").replace(' “'," ").replace('” '," ").replace('] '," ").replace(' ['," ")

s5 = s4.replace("  ", " ")
print(s5)

输出:

'This is a 1 example of the text But it only is 2.5 percent of all data'

Ps:你可以看看标点符号.replace(),并在函数中不断添加它们。

于 2017-03-31T14:36:44.563 回答
0

这是一种正则表达式方法

([^ ]?)(?:[^\P{punct}.]|(?<!\d)\.(?!\d))([^ ]?)

在回调中替换:

如果 $1 长度 > 0 且 $2 长度 > 0
替换为 $1 + 空格 + $2
否则替换为 $1$2

展开

 ( [^ ]? )                     # (1)
 (?:
      [^\P{punct}.] 
   |  
      (?<! \d )
      \.
      (?! \d )
 )
 ( [^ ]? )                     # (2)

如果您不想对与 punct 相邻的字符使用逻辑,
请使用(?:[^\P{punct}.]|(?<!\d)\.(?!\d))并替换为空。

于 2017-03-31T15:53:30.347 回答
0

我试过了,效果很好。

a = "This is a 1example of the text. But, it only is 2.5 percent of all data" a.replace(". ", " ").replace(", "," ")

请注意,在替换功能中,标点符号后有空格。我只是用空格替换了标点符号和空格。

于 2017-03-31T14:30:34.083 回答
0

我与 Python 脱节,但对正则表达式有一些了解。我建议使用or?我会使用这个 regexp: "(\d+)([a-zA-Z])|([a-zA-Z])(\d+)",然后作为替换字符串使用: "\1 \2"
如果某些极端情况困扰着你,你可以将反向引用传递给一个过程,然后一一处理,可能通过检查你的 "\1 \2" 可以转换为浮点数。TCL 有这样的内置功能,Python 也应该。

于 2017-03-31T14:15:44.570 回答