2014-02-11 55 views
1

我有一個推文列表,我必須選擇帶有「銷售」,「折扣」或「優惠」等條款的推文。此外,我還需要通過識別諸如「%」,「Rs」,「$」之類的內容來找到推廣特定交易(如折扣)的推文。我對正則表達式完全不瞭解,文檔也沒有讓我知道任何地方。這是我的代碼。這是相當糟糕的,但請原諒那個Python:某些條款的匹配字符串

import pymongo 
import re 
import datetime 
client = pymongo.MongoClient() 
db = client .PWSocial 
fourteen_days_ago = datetime.datetime.utcnow() - datetime.timedelta(days=14) 
id_list = [57947109, 183093247, 89443197, 431336956] 
ar1 = [" deal "," deals ", " offer "," offers " "discount", "promotion", " sale ", " inr", " rs", "%", "inr ", "rs ", " rs."] 
def func(ac_id): 
    mylist = [] 
    newlist = [] 
    tweets = list(db.tweets.find({'user_id' : ac_id, 'created_at': { '$gte': fourteen_days_ago }})) 
    for item in tweets: 
     data = item.get('text') 
     data = data.lower() 
     data = data.split() 
     flag = 0 
     if set(ar1).intersection(data): 
      flag = 1 
     abc = [] 
     for x in ar1: 
      for y in data: 
        if re.search(x,y): 
         abc.append(x) 
         flag = 1 
         break 
     if flag == 1: 
      mylist.append(item.get('id')) 
      newlist.append(abc) 
    print mylist 
    print newlist 
for i in id_list: 
    func(i) 

此代碼soen't給我任何正確的結果,並且是一個菜鳥到正則表達式,我想不出什麼不妥的地方。任何人都可以提出一個更好的方式來做這份工作嗎任何幫助表示讚賞。

回答

3

我的第一個建議 - 學習正則表達式,它給你一個無限的力量的文字處理。

但是,給你一些工作液(和起點,以進一步探索)試試這個:

import re 

re_offers = re.compile(r''' 
    \b # Word boundary 
     (?: # Non capturing parenthesis 
      deals? # Deal or deals 
      | # or ... 
      offers? # Offer or offers 
      | 
      discount 
      | 
      promotion 
      | 
      sale 
      | 
      rs\.? # rs or rs. 
      | 
      inr\d+ # INR then digits 
      | 
      \d+inr # Digits then INR 
     ) # And group 
    \b # Word boundary 
    | # or ... 
    \b\d+% # Digits (1 or more) then percent 
    | 
    \$\d+\b # Dollar then digits (didn't care of thousand separator yet) 
    ''', 
    re.I|re.X) # Ignore case, verbose format - for you :) 

abc = re_offers.findall("e misio $1 is inr123 discount 1INR a 1% and deal") 
print(abc) 
+0

我正在學習正則表達式,但我需要一個短期解決方案,直到我可以自己解決將來的這些問題。說實話,我發現我完全是正規表達的褲子,並且不能很快地學習它們。 –

+0

試試我的例子和實驗。我認爲它會解決你的問題,你不需要任何'split()','lower()'或嵌套'for'。另外,如果你給了我關於這個「inr」東西的更多信息,我可以爲這種情況提供更好的解決方案。 – Tupteq

+0

我是這麼做的。我意識到split()不是必需的。 INR代表'Indian National Rupee'。 –

1

你可能要考慮從find而不是一個正則表達式開始。您沒有複雜的表達式,並作爲你處理一行文字,你不需要調用split,而不是隻用find

for token in ar1: 
    if data.find(token) != -1: 
     abc.append(data) 

你在微博循環項目變爲:

for item in tweets: 
    data = item.get('text') 
    data = data.lower() 
    for x in ar1: 
     if data.find(x)  
      newlist.append(data) 
      mylist.append(item.get('id')) 
      break 

Re:你對jonsharpe的帖子的評論,爲了避免包含子字符串,用空格包圍你的標記,例如「RS」,「INR」

+0

數據就像是張貼流中的任意鳴叫多數民衆贊成,包括散列 - 標籤,用戶提及等。你說的不需要泄露()。一旦我嘗試jonsharpe的解決方案,我也意識到了這一點。 –

+0

用空格包圍我的標記實際上可能會變成一項非常繁瑣且耗時的工作。隨着項目規模的擴大,我工作的公司可能需要尋找越來越多的這種令牌。爲他們寫出不同的案例將是一項相當不錯的工作。 –

+0

您可以輕鬆自動執行任務。但更好的長期解決方案可能是去學習如何編譯正則表達式。 – jmetz

1

你並不需要使用這個正則表達式,你可以使用any

if any(term in tweet for term in search_terms): 
+0

謝謝。這工作。我只是想問你一些其他問題,以補充問題。正如你所看到的,諸如「rs」或「Rs」之類的東西可以有很多寫法。像INR這樣的詞可以是更長字符串中的子字符串。爲了解決這些問題,我認爲可能需要正則表達式。 –

+0

避免包含子字符串,用空格圍繞您的標記,例如「rs」,「INR」。 – jmetz

+0

爲了解決這個問題,我會把所有的東西都放在'lower()'('tweet' *和*'term')。 'in'將會找到例如''inr「in for saleinr250''沒有任何問題(實際上,你可能會遇到問題,比如在」inroads「中找到了太多的」inr「)。 – jonrsharpe

1

在你的東西陣列來搜索你沒有「優惠」之間的逗號「折扣」導致他們被聯合在一起。

另外,當你使用分割你擺脫了輸入文本中的空白。 「我有一筆交易」將成爲[「我」,「有」,「一個」,「交易」],但您的搜索條款幾乎都包含空格。所以刪除數組ar1中的搜索條件中的空格。

然而,你可能要避免使用正則表達式,只是使用替代(你仍然需要chnages我建議雖然以上):

if x in y: