2016-04-14 21 views
0

この問題は非常に単純ですが、ここではかなり失われています。正規表現を使用して入力テキストの特定のセクションのみを抽出する方法はありますか?

入力テキスト:

「レス/ RBRすべてのINの1月2日/ CD/IN/DT米国/ NNP企業は/ NNSは/ VBP 唯一/ JJの事業主/ NNS /である/よりも?。 '

コード:

def get_words(pos_sent): 
# Your code goes here 
    s = "" 
    x = re.findall(r"\b(\w*?)/\w*?\b", pos_sent) 
    for i in range(0, len(x)): 
     s = s + " " + x[i] 
    return s 

def get_noun_phrase(pos_sent): 
    # Penn Tagset 
    # Adjetive can be JJ,JJR,JJS 
    # Noun can be NN,NNS,NNP,NNPS 
    t = get_words(pos_sent) 
    regex = r'((\S+\/DT)?(\S+\/JJ)*(\S+\/NN)*(\S+\/NN))' 
    return re.findall(regex, t) 

最初の部分は、単に音声タグの一部を削除し、第二は、それを取ると、名詞句を見つけるためにそれを使用することになっています。

それが出力になっています:

[’all US businesses’, ’sole proprietorships’] 

ではなく、それは空のリストを出力:

[] 

さて、私はオリジナルのタグ付けされた文の中で取るためにそれを変更することができ、そして私が手:

[('all/DT US/NN', 'all/DT ', '', '', 'US/NN'), ('businesses/NN', '', '', '', 'businesses/NN'), ('sole/JJ proprietorships/NN', '', 'sole/JJ ', '', 'proprietorships/NN')] 

すべての正しいビットを持っていますが、それには他のものもたくさんあります。望んでいない。

私はまだ正規表現に新しいので、私はおそらく何か愚かな行方不明です。あなたの最初の関数の場合

+0

regexが最良の方法であるかどうかは分かりませんが、間違っている可能性があります>。 – Adib

+1

コードを正しくインデントする必要があります。必要に応じてヘルプ[here](https://stackoverflow.com/editing-help)があります。 – jDo

+0

あなたが提供した1つの文だけを照合するのはかなり簡単ですが、パターンに合わない他のテキストを解析しようとすると分解します。例えば。 "すべて/ DT US/NNPのビジネス/ NNS"と一致させるには、\ S +/DT \ S +/NNP \ S +/NNS "'を書き、出力に 'replace'または' translate'を実行すると、完了しました。しかし、 "all/DT businesses/NNS"にもマッチしたいのですか?何かは、文字列をステップ実行して次の単語/タグが有効なノードであるかどうかを判断するために、トライまたはグラフと再帰が必要であることを示しています。はいの場合は、それを新しい開始ノードにして、繰り返し/再帰します。いいえの場合は、パス/文を返します。 – jDo

答えて

0

、次の正規表現を使用 - \b([0-9A-z\/]*)\/\w*?\bを - あなたは「1/2」(出力テキストの改善フォーマットと一緒に)1/2としてではなく、1 2として滞在することを確実にすることができます

import re 

string = 'Less/RBR than/IN 1/2/CD of/IN all/DT US/NNP businesses/NNS are/VBP sole/JJ proprietorships/NNS ?/.' 

def create_relationship(pos_sent): 
    # Get all the words individually 
    words = re.findall(r'\b([0-9A-z\/]*)\/\w*?\b', pos_sent) 
    # ['Less', 'than', '1/2', 'of', 'all', 'US', 'businesses', 'are', 'sole', 'proprietorships'] 

    # Get all the tags individually 
    penn_tag = re.findall(r'\b[0-9A-z\/]*\/(\w*)?\b', pos_sent) 
    # ['RBR', 'IN', 'CD', 'IN', 'DT', 'NNP', 'NNS', 'VBP', 'JJ', 'NNS'] 

    # Create a relationship between the words and penn tag: 
    relationship = [] 
    for i in range(0,len(words)): 
     relationship.append([words[i],penn_tag[i]]) 

    # [['Less', 'RBR'], ['than', 'IN'], ['1/2', 'CD'], ['of', 'IN'], ['all', 'DT'], 
    # ['US', 'NNP'], ['businesses', 'NNS'], ['are', 'VBP'], ['sole', 'JJ'], ['proprietorships', 'NNS']] 

    return relationship 


def get_words(pos_sent): 
    # Pass string into relationship engine 
    array = create_relationship(pos_sent) 

    # Start with empty string 
    s = '' 

    # Conduct loop to combine string 
    for i in range(0, len(array)): 
     # index 0 has the words 
     s = s + array[i][0] + ' ' 

    # Return the sentence 
    return s 

def get_noun_phrase(pos_sent): 
    # Penn Tagset 
    # Adjetive can be JJ,JJR,JJS 
    # Noun can be NN,NNS,NNP,NNPS 
    # Noun Phrase must be made of: DT+RB+JJ+NN+PR (http://www.clips.ua.ac.be/pages/mbsp-tags) 

    # Pass string into relationship engine 
    array = create_relationship(pos_sent) 
    bucket = array 
    output = [] 

    # Find the last instance of NN where the next word is not "NN" 
    # For example, NNP VBP qualifies. In the case of NN NNP VBP, then 
    # the correct instance is NNP. To do this, we need to loop and use 
    # a bucket to capture what we need. The bucket will shirnk as we 
    # shrink the array to capture what we want 

    noun = True 

    # Keep doing this until there is no instances of Nouns 
    while noun: 

     # Would be ideal to have an if condition to see if there's a noun 
     # in the first place to stop this form working (and avoiding errors) 
     for i in range(0, len(bucket)): 
      if re.match(r'(NN.*)',bucket[i][1]): 
       # Set position of last noun 
       last_noun = i 

     noun_phrase = [] 

     # If we don't have noun, it'll stop the while loop 
     if last_noun < 0: 
      noun = False 
     else: 
      # go backwards from the point where you found the last noun 
      for x in range(last_noun, -1, -1): 
       # The penn tag must match any of these conditions 
       if re.match(r'(NN.*|DT.*|JJ.*|RB.*|PR.*)',bucket[x][1]): 
        # if there is a match, then let's build the word 
        noun_phrase.append(bucket[x][0]) 
        bucket.pop(x) 
       else: 
        last_noun = -1 
        break 

     # Make sure noun phrase isn't empty 
     if noun_phrase: 
      # Collect the noun phrase 
      output.append(" ".join(reversed(noun_phrase))) 

    # Fix the reverse issue 
    return [i for i in reversed(output)] 

print get_noun_phrase(string) 
# ['all US businesses', 'sole proprietorships'] 
+0

私は、私が持っているものは何かをしています:これは次のように出力します:[( 'all/DT US/NN'、 'all/DT'、 ''、 'US/NN')、 NJ '、' 'proprietorships/NN')]、[NJ]、[NJ]、[NJ ']、[NJ]すべての部分を持っています。 –

+0

@BNSlug追加のユースケースやサンプルがあり、その出力はどのように見えますか? – Adib

+0

私は、多分私はいくつかを見つけることができたことを意味します。名詞句は共通用語ではないのですか? –

関連する問題