-
Notifications
You must be signed in to change notification settings - Fork 19
/
Regex.php
111 lines (84 loc) · 3.73 KB
/
Regex.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
<?php declare(strict_types=1);
namespace Room11\Jeeves\Plugins;
use Amp\Promise;
use Amp\Success;
use Room11\Jeeves\Chat\Command;
use Room11\Jeeves\System\PluginCommandEndpoint;
use Room11\StackChat\Client\Client as ChatClient;
class Regex extends BasePlugin
{
private const HE_COMES
= "\x48\xCD\xA8\xCD\x8A\xCC\xBD\xCC\x85\xCC\xBE\xCC\x8E\xCC\xA1\xCC\xB8\xCC\xAA\xCC\xAF\x45\xCC\xBE"
. "\xCD\x9B\xCD\xAA\xCD\x84\xCC\x80\xCC\x81\xCC\xA7\xCD\x98\xCC\xAC\xCC\xA9\x20\xCD\xA7\xCC\xBE\xCD"
. "\xAC\xCC\xA7\xCC\xB6\xCC\xA8\xCC\xB1\xCC\xB9\xCC\xAD\xCC\xAF\x43\xCD\xAD\xCC\x8F\xCD\xA5\xCD\xAE"
. "\xCD\x9F\xCC\xB7\xCC\x99\xCC\xB2\xCC\x9D\xCD\x96\x4F\xCD\xAE\xCD\x8F\xCC\xAE\xCC\xAA\xCC\x9D\xCD"
. "\x8D\x4D\xCD\x8A\xCC\x92\xCC\x9A\xCD\xAA\xCD\xA9\xCD\xAC\xCC\x9A\xCD\x9C\xCC\xB2\xCC\x96\x45\xCC"
. "\x91\xCD\xA9\xCD\x8C\xCD\x9D\xCC\xB4\xCC\x9F\xCC\x9F\xCD\x99\xCC\x9E\x53\xCD\xAF\xCC\xBF\xCC\x94"
. "\xCC\xA8\xCD\x80\xCC\xA5\xCD\x85\xCC\xAB\xCD\x8E\xCC\xAD";
private $chatClient;
public function __construct(ChatClient $chatClient) {
$this->chatClient = $chatClient;
}
private function hasPattern(\DOMDocument $dom): bool {
return (bool) $dom->getElementsByTagName('code')->length;
}
private function zalgo(\DOMDocument $dom): bool {
return (bool) @preg_match('/<[^>]*\[\^[^\]]*>.*\\]/', $dom->getElementsByTagName('code')->item(0)->textContent);
}
private function doesMatch(\DOMDocument $dom): bool {
return (bool) @preg_match($dom->getElementsByTagName('code')->item(0)->textContent, $this->getSubject($dom));
}
private function hasCapturingGroups(\DOMDocument $dom): bool {
@preg_match($dom->getElementsByTagName('code')->item(0)->textContent, $this->getSubject($dom), $matches);
return count($matches) > 1;
}
private function getCapturingGroups(\DOMDocument $dom): string {
@preg_match($dom->getElementsByTagName('code')->item(0)->textContent, $this->getSubject($dom), $matches);
return "[ " . implode(" , ", array_slice($matches, 1)) . " ]";
}
private function getSubject(\DOMDocument $dom): string {
$clonedDom = clone $dom;
$pattern = $clonedDom->getElementsByTagName('code')->item(0);
$parent = $pattern->parentNode;
$parent->removeChild($pattern);
$subject = "";
foreach ($parent->childNodes as $child) {
$subject .= $parent->ownerDocument->saveHTML($child);
}
return $subject;
}
public function test(Command $command): Promise {
if (!$command->hasParameters()) {
return new Success();
}
$dom = new \DOMDocument();
$dom->loadHTML(implode(" ", $command->getParameters()));
if (!$this->hasPattern($dom)) {
return $this->chatClient->postReply($command, 'Pattern must be wrapped in a code block');
}
if ($this->zalgo($dom)) {
return $this->chatClient->postReply($command, self::HE_COMES);
}
if (!$this->doesMatch($dom)) {
return $this->chatClient->postReply($command, 'No match');
}
if (!$this->hasCapturingGroups($dom)) {
return $this->chatClient->postReply($command, 'Matches \o/');
}
return $this->chatClient->postReply(
$command,
"Matches with the following captured groups: " . $this->getCapturingGroups($dom)
);
}
public function getDescription(): string
{
return 'Evaluates regular expressions with PCRE';
}
/**
* @return PluginCommandEndpoint[]
*/
public function getCommandEndpoints(): array
{
return [new PluginCommandEndpoint('Test', [$this, 'test'], 'regex')];
}
}