OSDN Git Service

https://github.com/DavidCarrington/dabr
[embrj/master.git] / common / Regex.php
diff --git a/common/Regex.php b/common/Regex.php
new file mode 100644 (file)
index 0000000..accf174
--- /dev/null
@@ -0,0 +1,178 @@
+<?php
+/**
+ * @author     Mike Cochrane <mikec@mikenz.geek.nz>
+ * @author     Nick Pope <nick@nickpope.me.uk>
+ * @copyright  Copyright © 2010, Mike Cochrane, Nick Pope
+ * @license    http://www.apache.org/licenses/LICENSE-2.0  Apache License v2.0
+ * @package    Twitter
+ */
+
+/**
+ * Twitter Regex Abstract Class
+ *
+ * Used by subclasses that need to parse tweets.
+ *
+ * Originally written by {@link http://github.com/mikenz Mike Cochrane}, this
+ * is based on code by {@link http://github.com/mzsanford Matt Sanford} and
+ * heavily modified by {@link http://github.com/ngnpope Nick Pope}.
+ *
+ * @author     Mike Cochrane <mikec@mikenz.geek.nz>
+ * @author     Nick Pope <nick@nickpope.me.uk>
+ * @copyright  Copyright © 2010, Mike Cochrane, Nick Pope
+ * @license    http://www.apache.org/licenses/LICENSE-2.0  Apache License v2.0
+ * @package    Twitter
+ */
+abstract class Twitter_Regex {
+
+  /**
+   * Expression to at sign characters
+   *
+   * @var  string
+   */
+  const REGEX_AT_SIGNS = '[@@]';
+
+  /**
+   * Expression to match characters that may come before a URL.
+   *
+   * @var  string
+   */
+  const REGEX_URL_CHARS_BEFORE = '(?:[^-\\/"\':!=a-z0-9_@@]|^|\\:)';
+
+  /**
+   * Expression to match the domain portion of a URL.
+   *
+   * @var  string
+   */
+  const REGEX_URL_DOMAIN = '(?:[^\\p{P}\\p{Lo}\\s][\\.-](?=[^\\p{P}\\p{Lo}\\s])|[^\\p{P}\\p{Lo}\\s])+\\.[a-z]{2,}(?::[0-9]+)?';
+
+  /**
+   * Expression to match handful of probable TLDs for protocol-less URLS.
+   *
+   * @var  string
+   */
+  const REGEX_PROBABLE_TLD = '/\\.(?:com|net|org|gov|edu)$/iu';
+
+  /**
+   * Expression to match characters that may come in the URL path.
+   *
+   * @var  string
+   */
+  const REGEX_URL_CHARS_PATH = '(?:(?:\\([a-z0-9!\\*\';:=\\+\\$\\/%#\\[\\]\\-_,~]+\\))|@[a-z0-9!\\*\';:=\\+\\$\\/%#\\[\\]\\-_,~]+\\/|[\\.\\,]?(?:[a-z0-9!\\*\';:=\\+\\$\\/%#\\[\\]\\-_~]|,(?!\s)))';
+
+  /**
+   * Expression to match characters that may come at the end of the URL path.
+   *
+   * @var  string
+   */
+  const REGEX_URL_CHARS_PATH_END = '[a-z0-9=#\\/]';
+
+  /**
+   * Expression to match characters that may come in the URL query string.
+   *
+   * @var  string
+   */
+  const REGEX_URL_CHARS_QUERY = '[a-z0-9!\\*\'\\(\\);:&=\\+\\$\\/%#\\[\\]\\-_\\.,~]';
+
+  /**
+   * Expression to match characters that may come at the end of the URL query
+   * string.
+   *
+   * @var  string
+   */
+  const REGEX_URL_CHARS_QUERY_END = '[a-z0-9_&=#\\/]';
+
+  /**
+   * Expression to match a username followed by a list.
+   *
+   * @var  string
+   */
+  const REGEX_USERNAME_LIST = '/([^a-z0-9_\/]|^|RT:?)([@@]+)([a-z0-9_]{1,20})(\/[a-z][-_a-z0-9\x80-\xFF]{0,24})?([@@\xC0-\xD6\xD8-\xF6\xF8-\xFF]?)/iu';
+
+  /**
+   * Expression to match a username mentioned anywhere in a tweet.
+   *
+   * @var  string
+   */
+  const REGEX_USERNAME_MENTION = '/(^|[^a-z0-9_])[@@]([a-z0-9_]{1,20})([@@\xC0-\xD6\xD8-\xF6\xF8-\xFF]?)/iu';
+
+  /**
+   * Expression to match a hashtag.
+   *
+   * @var  string
+   */
+  const REGEX_HASHTAG = '/(^|[^0-9A-Z&\/\?]+)([##]+)([0-9A-Z_]*[A-Z_]+[a-z0-9_üÀ-ÖØ-öø-ÿ]*)/iu';
+
+  /**
+   * Expression to match whitespace.
+   *
+   * Single byte whitespace characters
+   *   0x0009-0x000D White_Space # Cc # <control-0009>..<control-000D>
+   *   0x0020        White_Space # Zs # SPACE
+   *   0x0085        White_Space # Cc # <control-0085>
+   *   0x00A0        White_Space # Zs # NO-BREAK SPACE
+   * Multi byte whitespace characters
+   *   0x1680        White_Space # Zs # OGHAM SPACE MARK
+   *   0x180E        White_Space # Zs # MONGOLIAN VOWEL SEPARATOR
+   *   0x2000-0x200A White_Space # Zs # EN QUAD..HAIR SPACE
+   *   0x2028        White_Space # Zl # LINE SEPARATOR
+   *   0x2029        White_Space # Zp # PARAGRAPH SEPARATOR
+   *   0x202F        White_Space # Zs # NARROW NO-BREAK SPACE
+   *   0x205F        White_Space # Zs # MEDIUM MATHEMATICAL SPACE
+   *   0x3000        White_Space # Zs # IDEOGRAPHIC SPACE
+   *
+   * @var  string
+   */
+  const REGEX_WHITESPACE = '[\x09-\x0D\x20\x85\xA0]|\xe1\x9a\x80|\xe1\xa0\x8e|\xe2\x80[\x80-\x8a,\xa8,\xa9,\xaf\xdf]|\xe3\x80\x80';
+
+  /**
+   * Contains the complete valid URL pattern string.
+   *
+   * This should be generated the first time the constructor is called.
+   *
+   * @var  string  The regex pattern for a valid URL.
+   */
+  protected static $REGEX_VALID_URL = null;
+
+  /**
+   * Contains the reply username pattern string.
+   *
+   * This should be generated the first time the constructor is called.
+   *
+   * @var  string  The regex pattern for a reply username.
+   */
+  protected static $REGEX_REPLY_USERNAME = null;
+
+  /**
+   * The tweet to be used in parsing.  This should be populated by the
+   * constructor of all subclasses.
+   *
+   * @var  string
+   */
+  protected $tweet = '';
+
+  /**
+   * This constructor is used to populate some variables.
+   *
+   * @param  string  $tweet  The tweet to parse.
+   */
+  protected function __construct($tweet) {
+    if (is_null(self::$REGEX_VALID_URL)) {
+      self::$REGEX_VALID_URL = '/(?:'             # $1 Complete match (preg_match already matches everything.)
+        . '('.self::REGEX_URL_CHARS_BEFORE.')'    # $2 Preceding character
+        . '('                                     # $3 Complete URL
+        . '((?:https?:\\/\\/|www\\.)?)'           # $4 Protocol (or www)
+        . '('.self::REGEX_URL_DOMAIN.')'          # $5 Domain(s) (and port)
+        . '(\\/'.self::REGEX_URL_CHARS_PATH.'*'   # $6 URL Path
+        . self::REGEX_URL_CHARS_PATH_END.'?)?'
+        . '(\\?'.self::REGEX_URL_CHARS_QUERY.'*'  # $7 Query String
+        . self::REGEX_URL_CHARS_QUERY_END.')?'
+        . ')'
+        . ')/iux';
+    }
+    if (is_null(self::$REGEX_REPLY_USERNAME)) {
+      self::$REGEX_REPLY_USERNAME = '/^('.self::REGEX_WHITESPACE.')*[@@]([a-zA-Z0-9_]{1,20})/';
+    }
+    $this->tweet = $tweet;
+  }
+
+}