I understand Lua does not have PCRE. How can I convert this into Lua?
# Quote shell chars
$a =~ s/[\002-\011\013-\032\\\#\?\`\(\)\{\}\[\]\^\*\<\=\>\~\|\; \"\!\$\&\'\202-\377]/\\$&/go;
# quote newline as '\n'
$a =~ s/[\n]/'\n'/go;
Is there a general converter that can convert any PCRE into Lua?
You may use
local a = "\002\003\004\005\006\007\008\009\010\011\012\\\n"
res, _ = a:gsub("([\002-\009\011-\026\\#?`(){}%[%]^*<>=~|; \"!$&'\130-\255])", "\\%1")
res, _ = res:gsub("\n", "'\n'")
print(res)
See Lua code demo
Note that in Lua patterns, \ is not a special char, % is used to replace special chars (like [) and \ddd escapes reference the decimal, not octal codes.
Related
I tried to split by "\", but this character is so special in Lua, even if I use escape character "%", the IDE shows an error Unterminated String constant
local index = string.find("lua. is \wonderful", "%\", 1)
To insert backslash \ into a quoted string, escape it with itself: "\\". \ is the escape character in regular quoted strings, so it is escaped with \. Or you can use the long string syntax, which doesn't allow escape sequences, as already pointed out: [[\]].
Percent is only an escape character in a string that is being used as a pattern, so it is used before the magical characters ^$()%.[]*+-? in the second argument to string.find, string.match, string.gmatch, and string.gsub, and %% represents % in the third argument to string.gsub.
The percent is still there in the string that is stored in memory, but backslash escape sequences are replaced with the corresponding character. \\ becomes \ when the string is stored in memory, and if you count the number of backslashes in a string "\\" using string.gsub, it will only find one: select(2, string.gsub("\\", "\\", "")) returns 1.
I am attempting to use this string:
var passwordRegex = "^[A-Za-z0-9 !\"#$%&'()*+,-./:;<=>?#[\\]^_`{|}~].{8,}$"
As my regular expression pattern, but it keeps failing saying the pattern is invalid. I used the \ character to escape for the characters: " and \, but it throws the error: invalid escape sequence in literal for regex key characters like ^ & [ ] | . etc.
What am I missing in order to allow the characters:
! " # $ % & ' ( ) * + , - . / : ; < = > ? # [ \ ] ^ _ ` { | } ~
(including space) in my regex? I assume it's something with how I am escaping, but I can't find anything anywhere for these characters in regards to SWIFT's regular expression.
The problem is that characters [, \, and ] need to be escaped because they have special meaning in a regular expression.
So you need \[, \\, and \] in the regular expression. But since this is inside a Swift string, each \ needs to be escaped with a \.
So [\] becomes \[\\\] in the regular expression which becomes \\[\\\\\\] in the Swift string.
The final valid string is:
var passwordRegex = "^[A-Za-z0-9 !\"#$%&'()*+,-./:;<=>?#\\[\\\\\\]^_`{|}~].{8,}$"
This is probably a rather trivial question for the Erlang experts - I'm trying to have my ejabberd server store offline messages (in a Riak db) which inherently do contain double quotes (") around various values, etc. I get a format error when I try to create a Riak database object from them, and testing of replacing the double quotes with an escape character (\") corrects the issue. The question is how can I do this replacement manually?
I tried the following code but somehow doesn't work.
(ejabberd#xxx-xx-xx-xxx)4> re:replace(""hello"", """, "\"", [{return, list}, global]).
* 1: syntax error before: hello
So essentially I'm trying to replace the embedded " around the hello word with \".
I don't know Erlang, but you probably need something like this:
"\"hello\"", "\"", "\\\""
You must escape both " and \ in replacement string.
The Erlang literal syntax for strings uses the "\" (backslash)
character as an escape code. You need to escape backslashes in literal
strings, both in your code and in the shell, with an additional
backslash, i.e.: "\".
Example:
Let's make an example. I use $ Erlang symbol which will be substituted with ascii integer of a character to show what is happening behind each string which basically is a list of integer.
Subject = [$"] ++ "hello" ++ [$"] = "\"hello\"".
Target = [$"] = "\"".
Replacement = [$\\, $\\, $"] = "\\\\\"".
Result = re:replace(Subject, Target, Replacement, [{return, list}, global]).
Now with getting the length of Subject and Result we can find the difference:
7 = length(Subject). %% => 7 characters: " h e l l o "
9 = length(Result). %% => 9 characters: \ " h e l l o \ "
English isn't my mother tongue,so it's a little hard to describe the question.
I wanna to get 'd=40' in str by lua string.gsub(),but there's some problem.
------code below---
local str =
[==[
-- a=10
- -b=20
--c=30
d=40
]==]
local pat1 = [=[%s[%s]]=]
local pat2 = [=[\n[%s]]=]
str:gsub(pat1, function(s) print("pat1>>" .. s) end) --pat1>>d=40
str:gsub(pat2, function(s) print("pat2<<" .. s) end) --not match
local re1,_ = str:gsub("\n","$")
local re2,_ = str:gsub("%s","$")
print(re1) --a=10$- -b=20$ --c=30$d=40$
print(re2) --$a=10$-$-b=20$$ --c=30$d=40$
As Lua 5.1 Reference Manual Say
%s: represents all space characters.
I Think it equal to '\n',' 'and'\t'.
Question : Why pat2 can't match?
But I think pat2 is right,there's a '\n'befor'd=40' ,
so I think It can match ,but it can't work,why?
When you use [[]] notation for strings, that's a special string literal that takes the string exactly as you provide it. No character escaping is done. You can put some number of = characters in the brackets, to make it a bit easier to let you use [ characters in the string.
The string literal "\n" is one character, representing the newline. That's because of the use of the escape character \. The escape character applied to the 'n' character means "the newline character."
The string literal [[\n]] is exactly what it says: the character '\' followed by the character 'n'. Because no escaping is done, \n is not treated specially. It's exactly what it looks like.
Therefore, when you say local pat2 = [=[\n[%s]]=] You're saying "the first character should be '\' followed by 'n' followed by a space. That's not what you want; you want the escaping to work. So you should use a regular string literal: local pat2 = "\n[%s]".
I read a file:
local logfile = io.open("log.txt", "r")
data = logfile:read("*a")
print(data)
output:
...
"(\.)\n(\w)", r"\1 \2"
"\n[^\t]", "", x, re.S
...
Yes, logfile looks awful as it's full of various commands
How can I call gsub and remove i.e. "(\.)\n(\w)", r"\1 \2" line from data variable?
Below snippet, does not work:
s='"(\.)\n(\w)", r"\1 \2"'
data=data:gsub(s, '')
I guess some escaping needs to be done. Any easy solution?
Update:
local data = [["(\.)\n(\w)", r"\1 \2"
"\n[^\t]", "", x, re.S]]
local s = [["(\.)\n(\w)", r"\1 \2"]]
local function esc(x)
return (x:gsub('%%', '%%%%')
:gsub('^%^', '%%^')
:gsub('%$$', '%%$')
:gsub('%(', '%%(')
:gsub('%)', '%%)')
:gsub('%.', '%%.')
:gsub('%[', '%%[')
:gsub('%]', '%%]')
:gsub('%*', '%%*')
:gsub('%+', '%%+')
:gsub('%-', '%%-')
:gsub('%?', '%%?'))
end
print(data:gsub(esc(s), ''))
This seems to works fine, only that I need to escape, escape character %, as it wont work if % is in matched string. I tried :gsub('%%', '%%%%') or :gsub('\%', '\%\%') but it doesn't work.
Update 2:
OK, % can be escaped this way if set first in above "table" which I just corrected
:terrible experience:
Update 3:
Escaping of ^ and $
As stated in Lua manual (5.1, 5.2, 5.3)
A caret ^ at the beginning of a pattern anchors the match at the beginning of the subject string. A $ at the end of a pattern anchors the match at the end of the subject string. At other positions, ^ and $ have no special meaning and represent themselves.
So a better idea would be to escape ^ and $ only when they are found (respectively) and the beginning or the end of the string.
Lua 5.1 - 5.2+ incompatibilities
string.gsub now raises an error if the replacement string contains a % followed by a character other than the permitted % or digit.
There is no need to double every % in the replacement string. See lua-users.
According to Programming in Lua:
The character `%´ works as an escape for those magic characters. So, '%.' matches a dot; '%%' matches the character `%´ itself. You can use the escape `%´ not only for the magic characters, but also for all other non-alphanumeric characters. When in doubt, play safe and put an escape.
Doesn't this mean that you can simply put % in front of every non alphanumeric character and be fine. This would also be future proof (in the case that new special characters are introduced). Like this:
function escape_pattern(text)
return text:gsub("([^%w])", "%%%1")
end
It worked for me on Lua 5.3.2 (only rudimentary testing was performed). Not sure if it will work with older versions.
Why not:
local quotepattern = '(['..("%^$().[]*+-?"):gsub("(.)", "%%%1")..'])'
string.quote = function(str)
return str:gsub(quotepattern, "%%%1")
end
to escape and then gsub it away?
try
line = '"(\.)\n(\w)", r"\1 \2"'
rx = '\"%(%\.%)%\n%(%\w%)\", r\"%\1 %\2\"'
print(string.gsub(line, rx, ""))
escape special characters with %, and quotes with \
Try s=[["(\.)\n(\w)", r"\1 \2"]].
Use stringx.replace() from Penlight Lua Libraries instead.
Reference: https://stevedonovan.github.io/Penlight/api/libraries/pl.stringx.html#replace
Implementation (v1.12.0): https://github.com/lunarmodules/Penlight/blob/1.12.0/lua/pl/stringx.lua#L288
Based on their implementation:
function escape(s)
return (s:gsub('[%-%.%+%[%]%(%)%$%^%%%?%*]','%%%1'))
end
function replace(s,old,new,n)
return (gsub(s,escape(old),new:gsub('%%','%%%%'),n))
end