The \Z anchor in BYOND's regex behaves how \z would.
\z should not match the end of a string only when there is a trailing newline whereas \Z should match the end of a string regardless of a trailing newline.
However when the \Z anchor is used in BYOND it only matches per \z when there is no trailing newline.
See: 'Strings Ending with a Line Break' section at http://www.regular-expressions.info/anchors.html and testbed https://regex101.com/r/cG5jN3/1
Numbered Steps to Reproduce Problem:
1. Run provided code
2. Add a newline to the end of testfile.txt
3. Rerun and compare result of outputs
Code Snippet (if applicable) to Reproduce Problem:
https://dl.dropboxusercontent.com/u/169349932/regextest.7z
var/output = file("output.txt")
var/file = file2text("testfile.txt")
/world/New()
output << file
any_3()
any_3_n()
any_3_n_n()
any_3_Z()
any_3_n_Z()
/proc/any_3()
var/regex/r = new("(.)(.)(.)")//should return 'CAT'
output << "-------"
if(r.Find(file))
output << "passed any_3 find()"
else
output << "failed any_3 find()"
output << r.name
output << r.match
/proc/any_3_n()
var/regex/r = new("(.)(.)(.)\n")//should return 'CAT\n'
output << "-------"
if(r.Find(file))
output << "passed any_3_n find()"
else
output << "failed any_3_n find()"
output << r.name
output << r.match
/proc/any_3_n_n()
var/regex/r = new("(.)(.)(.)\n\n")//should return 'BAT\n\n'
output << "-------"
if(r.Find(file))
output << "passed any_3_n_n find()"
else
output << "failed any_3_n_n find()"
output << r.name
output << r.match
/proc/any_3_Z()
var/regex/r = new("(.)(.)(.)\\Z")//should return 'COW', fails when there's a newline at end of file (\Z is meant to match the end of the string regardless of a trailing newline or not)
output << "-------"
if(r.Find(file))
output << "passed any_3_Z find()"
else
output << "failed any_3_Z find()"
output << r.name
output << r.match
/proc/any_3_n_Z()
var/regex/r = new("(.)(.)(.)\n\\Z")//should return 'COW\n' only when there's a newline at end of file (this is meant to be behavior of \z)
output << "-------"
if(r.Find(file))
output << "passed any_3_n_Z find()"
else
output << "failed any_3_n_Z find()"
output << r.name
output << r.match
Expected Results:
\Z to match with or without a trailing newline.
Actual Results:
\Z only matches when there is no trailing newline.
Does the problem occur:
Every time? Or how often? Yes
In other games? Yes
In other user accounts? Yes
On other computers? Yes
When does the problem NOT occur?
N/A
Did the problem NOT occur in any earlier versions? If so, what was the last version that worked? (Visit http://www.byond.com/download/build to download old versions for testing.)
This has occurred since 510 afaik.
Workarounds:
Using \n\Z when you know there'll be a trailing newline in your text; obviously this then fails if there isn't.