$re = '/^(?!##?\s)([^\/\|\@\"!]*?)(##|#[@?$%]{1,3}#|\$@?\$)/m';
$str = '## comment
# #comment
! Basic rules
##div
#@#div
##.ads
#@#.ads
###ads
#@##ads
example.com,~example.org##div
example.com,~example.org#@#div
example.com,~example.org##.ads
example.com,~example.org#@#.ads
example.com,~example.org###ads
example.com,~example.org#@##ads
! HTML filtering rules
! https://github.com/gorhill/uBlock/wiki/Static-filter-syntax#html-filters
example.com##^.badstuff
example.com##^script:has-text(7c9e3a5d51cdacfc)
! https://adguard.com/kb/general/ad-filtering/create-own-filters/#html-filtering-rules
example.org$$script[data-src="banner"]
example.org$@$script[data-src="banner"]
! CSS rules
! https://adguard.com/kb/general/ad-filtering/create-own-filters/#cosmetic-css-rules
example.com#$#div { visibility: hidden; }
example.com#@$#div { visibility: hidden; }
example.com#$#.textad { visibility: hidden; }
example.com#@$#.textad { visibility: hidden; }
example.com#$##textad { visibility: hidden; }
example.com#@$##textad { visibility: hidden; }
! Extended CSS selectors
! https://adguard.com/kb/general/ad-filtering/create-own-filters/#extended-css-selectors
example.com#?#div:has(> a[target="_blank"][rel="nofollow"])
example.com#@?#div:has(> a[target="_blank"][rel="nofollow"])
example.com#?#.banner:matches-css(width: 360px)
example.com#@?#.banner:matches-css(width: 360px)
example.com#?##banner:matches-css(width: 360px)
example.com#@?##banner:matches-css(width: 360px)
example.com#$?#div:has(> span) { display: none !important; }
example.com#@$?#div:has(> span) { display: none !important; }
example.com#$?#.banner:has(> span) { display: none !important; }
example.com#@$?#.banner:has(> span) { display: none !important; }
example.com#$?##banner:has(> span) { display: none !important; }
example.com#@$?##banner:has(> span) { display: none !important; }
! JavaScript rules
! https://adguard.com/kb/general/ad-filtering/create-own-filters/#javascript-rules
! https://adguard.com/kb/general/ad-filtering/create-own-filters/#scriptlets
example.com#%#window.__gaq = undefined;
example.com#@%#window.__gaq = undefined;
! Scriptlet rules
example.com##+js(aopw, Fingerprint2)
example.com#@#+js(aopw, Fingerprint2)
example.org,example.com#%#//scriptlet("abort-on-property-read", "alert")
example.com#@%#//scriptlet("abort-on-property-read")';
preg_match_all($re, $str, $matches, PREG_SET_ORDER, 0);
// Print the entire match result
var_dump($matches);
Please keep in mind that these code samples are automatically generated and are not guaranteed to work. If you find any syntax errors, feel free to submit a bug report. For a full regex reference for PHP, please visit: http://php.net/manual/en/ref.pcre.php