use strict;
my $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")';
my $regex = qr/^(?!##?\s)([^\/\|\@\"!]*?)(##|#[@?$%]{1,3}#|\$@?\$)/mp;
if ( $str =~ /$regex/g ) {
print "Whole match is ${^MATCH} and its start/end positions can be obtained via \$-[0] and \$+[0]\n";
# print "Capture Group 1 is $1 and its start/end positions can be obtained via \$-[1] and \$+[1]\n";
# print "Capture Group 2 is $2 ... and so on\n";
}
# ${^POSTMATCH} and ${^PREMATCH} are also available with the use of '/p'
# Named capture groups can be called via $+{name}
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 Perl, please visit: http://perldoc.perl.org/perlre.html