Nginx - Rewrite multiple parameters - regex

This may or may not be possible but thought I would ask.
We had recently changed some of the query parameters and wanted to 301 redirect the old version to the new version.
The old parameter scheme was categoryX=Y where X was some number and Y was some number (an example being category56=112). The new version just drops off the X so we have category=112. Now, this seems fairly simple enough to do if there is either a known number of parameters or a single parameter. However, there can be a variable number of these parameters. For example:
http://www.example.com/some_directory/index.shtml?category56=112
http://www.example.com/some_other_directory/index.shtml?category8=52&category11=2&other_param=12
I'm guessing there isn't a way to basically "for each" through the parameters and if a regex matches category(0-9+)=(0-9+) to change it to category=(0-9+)?

You can loop through your args but you will need the 3rd party Nginx Lua module which is also part of the Openresty Bundle.
With that in place, something along these lines should do the job ...
location /foo {
rewrite_by_lua '
local new_args = "exit"
local exit = false
local m, err = nil
-- load arguments
local args = ngx.req.get_uri_args()
-- loop through arguments and rebuild
for key, val in pairs(args) do
-- stop loop if "abort" arg is found
if key == "exit" then
exit = "true"
break
end
m, err = ngx.re.match(key, "category(0-9+)")
if m then
new_args = new_args .. "&category=" .. val
else
new_args = new_args .. "&" .. key .. "=" .. val
end
end
-- redirect if we have not been here before
if exit == "false" then
return ngx.redirect(ngx.var.scheme .. "://" .. ngx.var.host .. ngx.var.request_uri .. ngx.var.isargs .. new_args)
end
';
}

Related

Casting regex match to String

I created a simple code in Scala that checks whether an input is correctly formatted as HH:mm. I expect the code to result in an Array of valid strings. However, what I'm getting as a result is of type Any = Array(), which is problematic as when I try to print that result I get something like that:
[Ljava.lang.Object;#32a59591.
I guess it's a simple problem but being a Scala newbie I didn't manage to solve it even after a good few hours of googling and trial & error.
val scheduleHours = if (inputScheduleHours == "") {
dbutils.notebook.exit(s"ERROR: Missing param value for schedule hours.")
}
else {
val timePattern = """^((?:[0-30]?[0-9]|2[0-3]):[0-5][0-9])$""".r
val inputScheduleHoursParsed = inputScheduleHours.split(";").map(_.trim)
for (e <- inputScheduleHoursParsed) yield e match {
case timePattern(e) => e.toString
case _ => dbutils.notebook.exit(s"ERROR: Wrong param value for schedule hours: '${inputScheduleHours}'")
}
}
The problem is that some branches return the result you want and others return dbutils.notebook.exit which (I think) returns Unit. Scala must pick a type for the result that is compatible with both Unit and Array[String], and Any is the only one that fits.
One solution is to add a compatible value after the calls to dbutils.notebook.exit, e.g.
val scheduleHours = if (inputScheduleHours == "") {
dbutils.notebook.exit(s"ERROR: Missing param value for schedule hours.")
Array.empty[String]
}
Then all the branches return Array[String] so that will be the type of the result.

How to fix 'if statement with multi conditions' in lua

I use Lua in computercraft to automate the mining. But, my turtle whose program worked very well before, stops if it meets a lava/flowing_lava/water/flowing_water source.
Inside my program, I have a lot of function to manage, for example, the fuel management, the tunnel, the collision with gravel, and .. the detection if the turtle meets a "block".
If the block is just an air block, the turtle continues to advance, elseif the block isn't an air block, the turtle digs this block and doesn't move forward if there is still a block in front of her.
The problem? The four sources which I quoted previously are considered as blocks, and the turtle can't move forward.
I try to fix this problem with multi-condition into the if, but it's doesn't work, the turtle moves forward and dig in any direction.
So I think it's because my way of creating the if isn't good, maybe the syntax (for concatenating many or into () ).
How to solve this issue?
function blockDetection(position, justDetection)
success, detectionBlock = nil
block_name = ""
if position == "right" then
turtle.turnRight()
success, detectionBlock = turtle.inspect()
turtle.turnLeft()
if success then
block_name = detectionBlock.name
if justDetection == true and detectionBlock.name == "minecraft:air" then
block_name = true
elseif justDetection == true and detectionBlock.name ~= "minecraft:air" then
block_name = false
else
end
end
end
end
I think your problem is that you forgot to return block_name. If you omit the return statement, you implicitly return 0 arguments, so trying to access any would give nil values. For example
if blockDetection (position,justDetetcion) then --[[something]] end, would never execute the then-end block, since nil is considered false.
You should also one more thing you should change in your code:
You shouldn't use x==true. If x is a boolean, then if x==true then ... is equivalent to if x then ....
So, your code should look a like this:
function blockDetection(position, justDetection)
success, detectionBlock = nil
block_name = ""
if position == "right" then
turtle.turnRight()
success, detectionBlock = turtle.inspect()
turtle.turnLeft()
if success then
block_name = detectionBlock.name
if justDetection and detectionBlock.name == "minecraft:air" then
block_name = true
elseif justDetection and detectionBlock.name ~= "minecraft:air" then
block_name = false
else
end
end
end
return block_name
end

If contains and if does not Contain a colon, select the number

I have an IF statement that return the number, if there is a colon symbol in the string. Sometimes the string does not contain a colon symbol. I'm looking for an else statement that would select the only number "45061 if there is no colon in the string. A = Works when the string has a colon sign but I need some assistance with B, if the string does not have a colon.
A.
String/Text = OM_Account_Master_Slave~Account CP~3712011:Shared-001
B.
String/Text = OM_Account_Master_Slave~Account CP~45061Shared-001
A.
if(contains,":",Substring(Abbrev(),1,Subtract(Length(Abbrev()),11)))
Result = 3712011:Shared-001
B.
if(contains,":",Substring(Abbrev(),1,Subtract(Length(Abbrev()),11)))
else
Consider the following User Defined Function:
Public Function GetNumber(r As Range) As Variant
Dim v As String, capture As Boolean
Dim i As Long, t As String
v = r.Value
GetNumber = ""
If v = "" Then Exit Function
t = ""
capture = False
For i = 1 To Len(v)
m = Mid(v, i, 1)
If IsNumeric(m) Then
t = t & m
capture = True
Else
If capture Then Exit For
End If
Next i
If Len(t) > 0 Then
GetNumber = CLng(t)
End If
End Function
User Defined Functions (UDFs) are very easy to install and use:
ALT-F11 brings up the VBE window
ALT-I
ALT-M opens a fresh module
paste the stuff in and close the VBE window
If you save the workbook, the UDF will be saved with it.
If you are using a version of Excel later then 2003, you must save
the file as .xlsm rather than .xlsx
To remove the UDF:
bring up the VBE window as above
clear the code out
close the VBE window
To use the UDF from Excel:
=GetNumber(A1)
To learn more about macros in general, see:
http://www.mvps.org/dmcritchie/excel/getstarted.htm
and
http://msdn.microsoft.com/en-us/library/ee814735(v=office.14).aspx
and for specifics on UDFs, see:
http://www.cpearson.com/excel/WritingFunctionsInVBA.aspx
Macros must be enabled for this to work!

Powershell: How to Validate Range between 1 to 15 and it should accepts pattern as 1,2,3,4,5 to 15

I am a newbie in Power Shell Scripting.
I am trying to Achieve a functionality, that should accepts inputs from user in below criteria
Only Digits
Range Between 1 to 15
Should accept String of Array with comma Separated values ex: 1,2,3,4,14,15
Can Contain space in between commas
Values should not be duplicated
The Returned values must be Array
Till now, I have tried
Function Validate-Choice{
[cmdletbinding()]
Param(
[Parameter(Position=0,Mandatory=$True)]
[ValidateRange(1,15)]
[string[]]$Item
)
Process {$Item}
}
Validate-Choice 1,2,3,4,5,6,7,8,9,10,11,13 # Similar Way i want O/p
Out Put:
1
2
3
4
5
6
7
8
9
10
11
13
$ReadInput = Read-Host -prompt "Please Choose from the list [1/2/3/4/5/6/7/8/9/10/11/12/13/14] You can select multiple Values EX: 1, 2, 3 -- "
$userchoices = Validate-Choice -item $ReadInput
$userchoices
If read the same input from Host Getting Below Error
Validate-Choice : Cannot validate argument on parameter 'Item'. The argument cannot be validated because
its type "String" is not the same type (Int32) as the maximum and minimum limits of the parameter. Make sure the argument is of type Int32 and then try the command again. At line:10 char:21
+ Validate-Choice '1,2,3,4,5,6,7,8,9,10,11,13'
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidData: (:) [Validate-Choice], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationError,Validate-Choice
And also i am trying with different Regex patterns. But failing
Function Test-Something {
[cmdletbinding()]
Param(
[Parameter(Position=0,Mandatory=$True)]
[ValidatePattern('(?:\s*\d{1,15}[1-15]\s*(?:,|$))+$')]
[string[]]$Item
)
Process { $Item }
}
The above functions are partially resulting.
Can any one please help me here..!?
This would probably be easiest if you just changed the parameter type to [int[]] then your ValidateRange attribute does most of the work. It doesn't handle duplicates though. Turns out you can't use [ValidateScript()] as #PetSerAl points out. So that leaves checking the parameter the old fashioned way, in a begin block:
Function Test-Something {
[cmdletbinding()]
Param(
[Parameter(Position=0, Mandatory)]
[ValidateRange(1, 15)]
[int[]]$Item
)
Begin {
$ht = #{}
foreach ($i in $Item) {
if ($ht.ContainsKey("$i")) {
throw "Parameter Item must contain unique values - duplicate '$i'"
}
else {
$ht["$i"] = $i
}
}
}
Process {
[string]$Item
}
}
Test-Something (1,2,3,4,3)
Note that this won't work if you make the Item parameter accept pipeline input. In the pipeline input case, $Item will not be set in the begin block.
Naren_Ch
Your 1st usage of the advanced function (AF)
Validate-Choice 1,2,3,4,5,6,7,8,9,10,11,13 # Similar Way i want O/p
is correct - you are inputting data as expected by the AF.
Now, look at the example reading the input from the host:
$ReadInput = Read-Host -prompt "Please Choose from the list [1/2/3/4/5/6/7/8/9/10/11/12/13/14] You can select multiple Values EX: 1, 2, 3 -- "
When you do this, $ReadInput is a string, and in this case, it's a string full of commas!
Consequently, your data inputted to the AF will result in error caused by validation code, written by yourself.
To correct the situation, just do this:
$ReadInput = (Read-Host -prompt "Please Choose etc...") -split ','
$userchoices = Validate-Choice -item $ReadInput
You must remember that data read by Read-Host is a string (just 1 string).

How to disallow non-alphanumeric characters in ColdFusion using a RegEx

I am using ColdFusion 9.0.1.
I am trying to test whether a user has provided a non alphanumeric value. If they have, I want to return false. I'm pretty sure I am close, but I keep getting an error:
Complex object types cannot be converted to simple values.
I've tried multiple ways of making this work, but I can't get it to work.
Specifically, I want to allow only a through z and 0 through 9. No spaces, or special characters.
Can you help me tweak this?
<cfscript>
LOCAL.Description = trim(left(ARGUMENTS.Description, 15));
if (len(LOCAL.Description) lte 4) {
return false;
} else if (reMatchNoCase("[^A-Za-z0-9_]", LOCAL.Description) neq "") {
return false;
} else {
return true;
</cfscript>
W
reMatchNoCase returns Array which cannot be compared to the string, use ArrayLen() on the result in order to find out if there any matches
There is actually another problem in your code. First line will produce an error if the length of the description is less than 15, which means that the first IF is obsolete since it will always be false.
reMatchNoCase("[^A-Za-z0-9_]", LOCAL.Description) neq ""
It is because ReMatchNoCase returns an array, not a simple string. Either check the array length, or better yet, use ReFindNoCase instead. It returns the position of the first match, or 0 if it was not found.
You can also try the following approach:
<cfscript>
local.description = trim(local.description);
return reFind("(?i)^[A-Z0-9_]{5,}$", local.description)?true:false;
</cfscript>
I'm late to the party but reFindNoCase is the optimal solution in 2021. Here's how I would handle the code in the original question:
// best practice not to have a local var name identical to an argument var
var myValue = trim( left( arguments.description, 15 ) );
// return false if myValue is less than 4 or has special characters
return(
!len( myValue ) lte 4 &&
!reFindNoCase( "[^a-z0-9]", myValue )
);