ó
ł`]c        	   @  sB  d  Z  d d l m Z d d l Z d d l m Z m Z d d l m Z d Z	 d Z
 e
 d e	 d	 d
 d d d d f	 Z e j d d j e  e j e j Be j B Z e j d  Z e j e	 e j e j Be j B Z e j d  Z d d d  Z d e d d  Z d d d     YZ d   Z d   Z e e e d  Z d S(   u  
Twitter-aware tokenizer, designed to be flexible and easy to adapt to new
domains and tasks. The basic logic is this:

1. The tuple regex_strings defines a list of regular expression
   strings.

2. The regex_strings strings are put, in order, into a compiled
   regular expression object called word_re.

3. The tokenization is done by word_re.findall(s), where s is the
   user-supplied string, inside the tokenize() method of the class
   Tokenizer.

4. When instantiating Tokenizer objects, there is a single option:
   preserve_case.  By default, it is set to True. If it is set to
   False, then the tokenizer will downcase everything except for
   emoticons.

i’’’’(   t   unicode_literalsN(   t   int2bytet   unichr(   t   html_entitiesuc  
    (?:
      [<>]?
      [:;=8]                     # eyes
      [\-o\*\']?                 # optional nose
      [\)\]\(\[dDpP/\:\}\{@\|\\] # mouth
      |
      [\)\]\(\[dDpP/\:\}\{@\|\\] # mouth
      [\-o\*\']?                 # optional nose
      [:;=8]                     # eyes
      [<>]?
      |
      <3                         # heart
    )u  			# Capture 1: entire matched URL
  (?:
  https?:				# URL protocol and colon
    (?:
      /{1,3}				# 1-3 slashes
      |					#   or
      [a-z0-9%]				# Single letter or digit or '%'
                                       # (Trying not to match e.g. "URI::Escape")
    )
    |					#   or
                                       # looks like domain name followed by a slash:
    [a-z0-9.\-]+[.]
    (?:[a-z]{2,13})
    /
  )
  (?:					# One or more:
    [^\s()<>{}\[\]]+			# Run of non-space, non-()<>{}[]
    |					#   or
    \([^\s()]*?\([^\s()]+\)[^\s()]*?\) # balanced parens, one level deep: (...(...)...)
    |
    \([^\s]+?\)				# balanced parens, non-recursive: (...)
  )+
  (?:					# End with:
    \([^\s()]*?\([^\s()]+\)[^\s()]*?\) # balanced parens, one level deep: (...(...)...)
    |
    \([^\s]+?\)				# balanced parens, non-recursive: (...)
    |					#   or
    [^\s`!()\[\]{};:'".,<>?Ā«Ā»āāāā]	# not a space or one of these punct chars
  )
  |					# OR, the following to match naked domains:
  (?:
  	(?<!@)			        # not preceded by a @, avoid matching foo@_gmail.com_
    [a-z0-9]+
    (?:[.\-][a-z0-9]+)*
    [.]
    (?:[a-z]{2,13})
    \b
    /?
    (?!@)			        # not succeeded by a @,
                            # avoid matching "foo.na" in "foo.na@example.com"
  )
u	  
    (?:
      (?:            # (international)
        \+?[01]
        [ *\-.\)]*
      )?
      (?:            # (area code)
        [\(]?
        \d{3}
        [ *\-.\)]*
      )?
      \d{3}          # exchange
      [ *\-.\)]*
      \d{4}          # base
    )u	   <[^>\s]+>u   [\-]+>|<[\-]+u   (?:@[\w_]+)u   (?:\#+[\w_]+[\w\'_\-]*[\w_]+)u#   [\w.+-]+@[\w-]+\.(?:[\w-]\.?)+[\w-]u  
    (?:[^\W\d_](?:[^\W\d_]|['\-_])+[^\W\d_]) # Words with apostrophes or dashes.
    |
    (?:[+\-]?\d+[,/.:-]\d+[+\-]?)  # Numbers, including fractions, decimals.
    |
    (?:[\w_]+)                     # Words without apostrophes or dashes.
    |
    (?:\.(?:\s*\.){1,})            # Ellipsis dots.
    |
    (?:\S)                         # Everything else that isn't whitespace.
    u   (%s)u   |u   ([^a-zA-Z0-9])\1{3,}u   &(#?(x?))([^&;\s]+);u   strictc         C  s8   | d  k r d } n  t |  t  r4 |  j | |  S|  S(   Nu   utf-8(   t   Nonet
   isinstancet   bytest   decode(   t   textt   encodingt   errors(    (    s3   lib/python2.7/site-packages/nltk/tokenize/casual.pyt   _str_to_unicode»   s
    	u   utf-8c           s+      f d   } t  j | t |  |   S(   u·  
    Remove entities from text by converting them to their
    corresponding unicode character.

    :param text: a unicode string or a byte string encoded in the given
    `encoding` (which defaults to 'utf-8').

    :param list keep:  list of entity names which should not be replaced.    This supports both numeric entities (``&#nnnn;`` and ``&#hhhh;``)
    and named entities (such as ``&nbsp;`` or ``&gt;``).

    :param bool remove_illegal: If `True`, entities that can't be converted are    removed. Otherwise, entities that can't be converted are kept "as
    is".

    :returns: A unicode string with the entities removed.

    See https://github.com/scrapy/w3lib/blob/master/w3lib/html.py

        >>> from nltk.tokenize.casual import _replace_html_entities
        >>> _replace_html_entities(b'Price: &pound;100')
        'Price: \xa3100'
        >>> print(_replace_html_entities(b'Price: &pound;100'))
        Price: Ā£100
        >>>
    c           s  |  j  d  } |  j  d  r yc |  j  d  rB t | d  } n t | d  } d | k oh d k n r t |  j d  SWqÉ t k
 r d  } qÉ Xn+ |   k r· |  j  d	  St j j |  } | d  k	 rś y t	 |  SWqś t k
 rö qś Xn   rd
 S|  j  d	  S(   Ni   i   i   i   i
   i   i   u   cp1252i    u    (
   t   groupt   intR   R   t
   ValueErrorR   R   t   name2codepointt   getR   (   t   matcht   entity_bodyt   number(   t   keept   remove_illegal(    s3   lib/python2.7/site-packages/nltk/tokenize/casual.pyt   _convert_entityß   s&    (   t   ENT_REt   subR   (   R   R   R   R	   R   (    (   R   R   s3   lib/python2.7/site-packages/nltk/tokenize/casual.pyt   _replace_html_entitiesĆ   s    t   TweetTokenizerc           B  s)   e  Z d  Z e e e d  Z d   Z RS(   u°  
    Tokenizer for tweets.

        >>> from nltk.tokenize import TweetTokenizer
        >>> tknzr = TweetTokenizer()
        >>> s0 = "This is a cooool #dummysmiley: :-) :-P <3 and some arrows < > -> <--"
        >>> tknzr.tokenize(s0)
        ['This', 'is', 'a', 'cooool', '#dummysmiley', ':', ':-)', ':-P', '<3', 'and', 'some', 'arrows', '<', '>', '->', '<--']

    Examples using `strip_handles` and `reduce_len parameters`:

        >>> tknzr = TweetTokenizer(strip_handles=True, reduce_len=True)
        >>> s1 = '@remy: This is waaaaayyyy too much for you!!!!!!'
        >>> tknzr.tokenize(s1)
        [':', 'This', 'is', 'waaayyy', 'too', 'much', 'for', 'you', '!', '!', '!']
    c         C  s   | |  _  | |  _ | |  _ d  S(   N(   t   preserve_caset
   reduce_lent   strip_handles(   t   selfR   R   R   (    (    s3   lib/python2.7/site-packages/nltk/tokenize/casual.pyt   __init__  s    		c         C  s   t  |  } |  j r$ t |  } n  |  j r< t |  } n  t j d |  } t j |  } |  j	 s t
 t d   |   } n  | S(   u¾   
        :param text: str
        :rtype: list(str)
        :return: a tokenized list of strings; concatenating this list returns        the original string if `preserve_case=False`
        u   \1\1\1c         S  s   t  j |   r |  S|  j   S(   N(   t   EMOTICON_REt   searcht   lower(   t   x(    (    s3   lib/python2.7/site-packages/nltk/tokenize/casual.pyt   <lambda>/  t    (   R   R   t   remove_handlesR   t   reduce_lengtheningt   HANG_RER   t   WORD_REt   findallR   t   listt   map(   R   R   t	   safe_textt   words(    (    s3   lib/python2.7/site-packages/nltk/tokenize/casual.pyt   tokenize  s    			(   t   __name__t
   __module__t   __doc__t   Truet   FalseR   R/   (    (    (    s3   lib/python2.7/site-packages/nltk/tokenize/casual.pyR     s   c         C  s   t  j d  } | j d |   S(   ue   
    Replace repeated character sequences of length 3 or greater with sequences
    of length 3.
    u	   (.)\1{2,}u   \1\1\1(   t   ret   compileR   (   R   t   pattern(    (    s3   lib/python2.7/site-packages/nltk/tokenize/casual.pyR'   9  s    c         C  s   t  j d  } | j d |   S(   u4   
    Remove Twitter username handles from text.
    uv   (?<![A-Za-z0-9_!@#\$%&*])@(([A-Za-z0-9_]){20}(?!@))|(?<![A-Za-z0-9_!@#\$%&*])@(([A-Za-z0-9_]){1,19})(?![A-Za-z0-9_]*@)u    (   R5   R6   R   (   R   R7   (    (    s3   lib/python2.7/site-packages/nltk/tokenize/casual.pyR&   B  s    	c         C  s"   t  d | d | d |  j |   S(   u:   
    Convenience function for wrapping the tokenizer.
    R   R   R   (   R   R/   (   R   R   R   R   (    (    s3   lib/python2.7/site-packages/nltk/tokenize/casual.pyt   casual_tokenizeR  s    (    (    (   R2   t
   __future__R    R5   t   sixR   R   t	   six.movesR   t	   EMOTICONSt   URLSt   REGEXPSR6   t   joint   VERBOSEt   It   UNICODER)   R(   R    R   R   R   R3   R   R   R'   R&   R4   R8   (    (    (    s3   lib/python2.7/site-packages/nltk/tokenize/casual.pyt   <module>!   s2   .	0#?7			