I have a variable aa which is having reference to an environment variable.
And I need to substitute the value using regex
Name = TEMP
Value = C:\Users\asus101\AppData\Local\Temp
aa: String = "${TEMP}_Report"
Expected output:
p2: C:\Users\asus101\AppData\Local\Temp_Report
The code that I tried
import scala.collection.JavaConversions._
val aa = "${TEMP}\\Report"
for ((name,value) <- System.getenv() ) {
val p1 = """\${XX}""".replace("XX",name).r
val p2 = p1.replaceAllIn(aa,value)
if(name=="TEMP") {
println("Name = " + name)
println("Value = " + value)
println("p2 = " + p2 )
}
I'm getting the error as
Exception in thread "main" java.util.regex.PatternSyntaxException: Illegal repetition near index 1
\${USERDOMAIN_ROAMINGPROFILE}
^
what is wrong with the regex
It's a little hard to tell, but I think this gets at what you're after.
import scala.util.Properties._
val pttrn = raw".*(\$$\{\s*(\w+)\s*\})".r
val strA = "${ME}:my ${HOME} is Gnome and my ${BROWSER} is fine."
val strB =
strA.split("(?<=})").map {
case s # pttrn(a,b) => envOrNone(b).fold(s)(s.replace(a,_))
case s => s
}.mkString
//strB: String = ${ME}:my /home/jwvh is Gnome and my firefox is fine.
There is no $ME in my environment, so no substitution there, but the $HOME and $BROWSER values are pulled out and substituted.
Related
This question is somewhat similar to this, but my task is to place something, in my case the dash, between the repeating characters, for example the question marks, using the gsub function.
Example:
"?" = "?"
"??" = "?-?"
"??? = "?-?-?"
Try this:
function test(s)
local t=s:gsub("%?%?","?-?"):gsub("%?%?","?-?")
print(#s,s,t)
end
for n=0,10 do
test(string.rep("?",n))
end
A possible solution using LPeg:
local lpeg = require 'lpeg'
local head = lpeg.C(lpeg.P'?')
local tail = (lpeg.P'?' / function() return '-?' end) ^ 0
local str = lpeg.Cs((head * tail + lpeg.P(1)) ^ 1)
for n=0,10 do
print(str:match(string.rep("?",n)))
end
print(str:match("?????foobar???foo?bar???"))
This what i can came out with scanning each letter by letter
function test(str)
local output = ""
local tab = {}
for let in string.gmatch(str, ".") do
table.insert(tab, let)
end
local i = 1
while i <= #tab do
if tab[i - 1] == tab[i] then
output = output.."-"..tab[i]
else
output = output..tab[i]
end
i = i + 1
end
return output
end
for n=0,10 do
print(test(string.rep("?",n)))
end
I have for example
str = "Beamer-Template!navigation symbols#\\texttt {navigation symbols}"
print(str:gsub('[^!|#%s]+#', ''))
which prints
Beamer-Template!navigation \texttt {navigation symbols}
but it should be
Beamer-Template!\texttt {navigation symbols}
How can I catch the space?
Important is only the foo#bar. The pattern works fine for strings like
str="foo#bar!baz#foobar!nice|crazy"
-> bar!foobar!nice|crazy
but not with an additional space
str="foo#bar!baz baz#foobar!nice|crazy"
-> bar!baz foobar!nice|crazy
which should be bar!foobar!nice|crazy
To match makeindex entries it might be useful to use an LPEG grammar. This way you can split at the separators and even perform semantic actions, depending on the matched field.
local lpeg = assert(require"lpeg")
local C, S = lpeg.C, lpeg.S
local sep = S("#!|")
local str = C((1 - sep)^0)
local idx = str * ( "#" * str / function(match) return "#" .. match end
+ "!" * str / function(match) return "!" .. match end
+ "|" * str / function(match) return "|" .. match end)^0
print(idx:match("hello!world#foo|bar"))
$ lua test.lua
hello !world #foo |bar
Answer to the comment: Collecting the matches in a table. The matches are collected according to their prefix.
local lpeg = assert(require"lpeg")
local C, Ct, S = lpeg.C, lpeg.Ct, lpeg.S
local sep = S("#!|")
local str = C((1 - sep)^0)
local match = function(expr)
local prefix = function(prefix)
return function(match)
return prefix .. match
end
end
local idx = str * ( "#" * str / prefix("#")
+ "!" * str / prefix("!")
+ "|" * str / prefix("|"))^0
return Ct(idx):match(expr)
end
for _, str in ipairs{
"hello!world#foo|bar",
"foo#bar!baz baz#foobar!nice|crazy",
"foo#bar!baz#foobar!nice|crazy",
"Beamer-Template!navigation symbols#\\texttt {navigation symbols}"
} do
local t = match(str)
print(table.concat(t," "))
end
$ lua test.lua
hello !world #foo |bar
foo #bar !baz baz #foobar !nice |crazy
foo #bar !baz #foobar !nice |crazy
Beamer-Template !navigation symbols #\texttt {navigation symbols}
I am trying to do regex on a number based on the below conditions, however its returning an empty string
import java.util.regex.Matcher
import java.util.regex.Pattern
object clean extends App {
val ALPHANUMERIC: Pattern = Pattern.compile("^[a-zA-Z0-9]*$")
val SPECIALCHAR: Pattern = Pattern.compile("[a-zA-Z0-9\\-#\\.\\(\\)\\/%&\\s]")
val LEADINGZEROES: Pattern = Pattern.compile("^[0]+(?!$)")
val TRAILINGZEROES: Pattern = Pattern.compile("\\.0*$|(\\.\\d*?)0+$")
def evaluate(codes: String): String = {
var str2: String = codes.toString
var text:Matcher = LEADINGZEROES.matcher(str2)
str2 = text.replaceAll("")
text = ALPHANUMERIC.matcher(str2)
str2 = text.replaceAll("")
text = SPECIALCHAR.matcher(str2)
str2 = text.replaceAll("")
text = TRAILINGZEROES.matcher(str2)
str2 = text.replaceAll("")
}
}
the code is returning empty string for LEADINGZEROES match.
scala> println("cleaned value :" + evaluate("0001234"))
cleaned value :
What change should I do to make the code work as I expect. Basically i am trying to remove leading/trailing zeroes and if the numbers has special characters/alphanumeric values than entire value should be returned null
Your LEADINGZEROES pattern is working correct as
val LEADINGZEROES: Pattern = Pattern.compile("^[0]+(?!$)")
println(LEADINGZEROES.matcher("0001234").replaceAll(""))
gives
//1234
But then there is a pattern matching
text = ALPHANUMERIC.matcher(str2)
which replaces all alphanumeric to "" and this made str as empty ("")
As when you do
val ALPHANUMERIC: Pattern = Pattern.compile("^[a-zA-Z0-9]*$")
val LEADINGZEROES: Pattern = Pattern.compile("^[0]+(?!$)")
println(ALPHANUMERIC.matcher(LEADINGZEROES.matcher("0001234").replaceAll("")).replaceAll(""))
it will print empty
Updated
As you have commented
if there is a code that is alphanumeric i want to make that value NULL
but in case of leading or trailing zeroes its pure number, which should return me the value after removing zeroes
but its also returning null for trailing and leading zeroes matches
and also how can I skip a match , suppose i want the regex to not match the number 0999 for trimming leading zeroes
You can write your evaluate function and regexes as below
val LEADINGTRAILINGZEROES = """(0*)(\d{4})(0*)""".r
val ALPHANUMERIC = """[a-zA-Z]""".r
def evaluate(codes: String): String = {
val LEADINGTRAILINGZEROES(first, second, third) = if(ALPHANUMERIC.findAllIn(codes).length != 0) "0010" else codes
if(second.equalsIgnoreCase("0010")) "NULL" else second
}
which should give you
println("cleaned value : " + evaluate("000123400"))
// cleaned value : 1234
println("alphanumeric : " + evaluate("0001A234"))
// alphanumeric : NULL
println("skipping : " + evaluate("0999"))
// skipping : 0999
I hope the answer is helpful
I want to create a shortcut in libreoffice to replace spaces by underscore.
I recorded a macro
I performed a simple find & replace.
But everytime I try to run the macro libreoffice quit ;(
this is the code
REM ***** BASIC *****
sub replacespaces
rem ----------------------------------------------------------------------
rem define variables
dim document as object
dim dispatcher as object
rem ----------------------------------------------------------------------
rem get access to the document
document = ThisComponent.CurrentController.Frame
dispatcher = createUnoService("com.sun.star.frame.DispatchHelper")
rem ----------------------------------------------------------------------
dim args1(17) as new com.sun.star.beans.PropertyValue
args1(0).Name = "SearchItem.StyleFamily"
args1(0).Value = 2
args1(1).Name = "SearchItem.CellType"
args1(1).Value = 0
args1(2).Name = "SearchItem.RowDirection"
args1(2).Value = true
args1(3).Name = "SearchItem.AllTables"
args1(3).Value = false
args1(4).Name = "SearchItem.Backward"
args1(4).Value = false
args1(5).Name = "SearchItem.Pattern"
args1(5).Value = false
args1(6).Name = "SearchItem.Content"
args1(6).Value = false
args1(7).Name = "SearchItem.AsianOptions"
args1(7).Value = false
args1(8).Name = "SearchItem.AlgorithmType"
args1(8).Value = 1
args1(9).Name = "SearchItem.SearchFlags"
args1(9).Value = 71680
args1(10).Name = "SearchItem.SearchString"
args1(10).Value = " "
args1(11).Name = "SearchItem.ReplaceString"
args1(11).Value = "_"
args1(12).Name = "SearchItem.Locale"
args1(12).Value = 255
args1(13).Name = "SearchItem.ChangedChars"
args1(13).Value = 2
args1(14).Name = "SearchItem.DeletedChars"
args1(14).Value = 2
args1(15).Name = "SearchItem.InsertedChars"
args1(15).Value = 2
args1(16).Name = "SearchItem.TransliterateFlags"
args1(16).Value = 1280
args1(17).Name = "SearchItem.Command"
args1(17).Value = 3
dispatcher.executeDispatch(document, ".uno:ExecuteSearch", "", 0, args1())
rem ----------------------------------------------------------------------
dispatcher.executeDispatch(document, ".uno:SearchResultsDialog", "", 0, Array())
end sub
Can someone tell me what's wrong ?
The macro recorder of openoffice and libreoffice is not really so much helpful as the one of Microsoft Office. I would suggest not to use it. Instead recording a macro, use a tool like XRAY ( https://wiki.documentfoundation.org/Macros) for examining the objects you have found using the methods of the API. At first examine thisComponent. Doing so, with Calc, you will find a model which has multiple models of sheets which each implements an interface XReplaceable (http://api.libreoffice.org/docs/idl/ref/interfacecom_1_1sun_1_1star_1_1util_1_1XReplaceable.html).
Example:
Sub findAndReplace()
oModel = thisComponent ' at first examine thisComponent
' xray oModel
oSpreadSheet = oModel.getCurrentController().getActiveSheet()
' oSpreadSheet = oModel.getSheets().getByIndex(0)
' xray oSpreadSheet
xReplaceDescr = oSpreadSheet.createReplaceDescriptor()
' xray xReplaceDescr
xReplaceDescr.SearchString = " "
xReplaceDescr.ReplaceString = "_"
lFound = oSpreadSheet.replaceAll(xReplaceDescr)
' xray lFound
MsgBox lFound & " replacements done."
End Sub
Spent a week trying to figure this out, so far, so I'm not just jumping here first - and all Microsoft sites tend to focus on Excel which seems to be non-appropriate for what I'm doing:
I'm attempting to use this VBA script to open up multiple WORD files, in succession, run a Find/Selection to grab a specific pattern, and then copy all occurrences into another WORD file.
This code is a mix of something I found online (though can't recall where, at this point) and my own tinkering. I've been able to DEBUG.PRINT the correct output, but no way to continue to move through my file to copy specific lines and then paste them. I feel it has something to do with the .Activate calls:
Sub x()
Dim GetStr(5000) As String
Const wdStory = 4
Const wdExtend = 1
'Set Doc = Documents.Open(FileName:="C:\Users\...\filename.CDS", Visible:=True)
'Set Doc = Documents.Open("C:\Users\...\filename.CDS")
Set MyDialog = Application.FileDialog(msoFileDialogFilePicker)
With MyDialog
.Filters.Clear
.Filters.Add "All WORD File ", "*.CDS", 1
.AllowMultiSelect = True
i = 2 'set to 2 in order to offset the open word window that houses the VBA
If .Show = -1 Then
For Each stiSelectedItem In .SelectedItems
GetStr(i) = stiSelectedItem
i = i + 1
Next
i = i - 1
End If
Set objWord = CreateObject("Word.Application")
objWord.Visible = True
objWord.Documents.Open ("C:\Users\...\filename.docx")
For j = 2 To i Step 1
Set objDoc = objWord.Documents.Open(GetStr(j))
'Debug.Print (objWord.Documents(1).Name)
Set objSelection = objWord.Selection
objSelection.Find.Forward = True
objSelection.Find.MatchWildcards = True
objSelection.Find.Text = "DEFINE"
Do While True
objSelection.Find.Execute
Debug.Print (objSelection)
If objSelection.Find.Found Then
objSelection.EndOf wdStory, wdExtend 'get selection
strText = objSelection.Copy 'strText = selection copied to clipboard, no value (like an inline function)
Set selectionToPaste = objWord.Selection 'selectionToPaste is literally the clipboard
'objWord.Documents(2).Activate
'Debug.Print ("->'Activated Window': " + objWord.ActiveDocument.Name)
'Debug.Print ("selectionToPaste = " + selectionToPaste)
selectionToPaste.Paste
'objWord.Documents(1).Activate
objSelection.Find.Execute
Else
objWord.ActiveDocument.Save
objWord.ActiveWindow.Close
Exit Do
End If
Loop
Next
End With
End Sub
OP here - Solved my own problem utilizing a loop.
Sub x()
Dim GetStr(5000) As String
**Dim iCounter As Integer**
Const wdStory = 4
Const wdExtend = 1
'Set Doc = Documents.Open(FileName:="C:\Users\...\filename.CDS", Visible:=True)
'Set Doc = Documents.Open("C:\Users\...\filename.CDS")
Set MyDialog = Application.FileDialog(msoFileDialogFilePicker)
With MyDialog
.Filters.Clear
.Filters.Add "All WORD File ", "*.CDS", 1
.AllowMultiSelect = True
i = 2 'set to 2 in order to offset the open word window that houses the VBA
If .Show = -1 Then
For Each stiSelectedItem In .SelectedItems
GetStr(i) = stiSelectedItem
i = i + 1
Next
i = i - 1
End If
Set objWord = CreateObject("Word.Application")
objWord.Visible = True
objWord.Documents.Open ("C:\Users\lidm3b2\Desktop\gar\2.docx")
For j = 2 To i Step 1
Set objDoc = objWord.Documents.Open(GetStr(j))
'Debug.Print (objWord.Documents(1).Name)
Set objSelection = objWord.Selection
objSelection.Find.Forward = True
objSelection.Find.MatchWildcards = True
objSelection.Find.Text = "DEFINE"
**iCounter = 0**
Do While True
**For iLoopCounter = 0 To iCounter Step 1
objSelection.Find.Execute
Next**
Debug.Print (objSelection)
If objSelection.Find.Found Then
objSelection.EndOf wdStory, wdExtend 'get selection
strText = objSelection.Copy 'strText = selection copied to clipboard, no value (like an inline function)
Set selectionToPaste = objWord.Selection 'selectionToPaste is literally the clipboard
objWord.Documents(2).Activate
'Debug.Print ("->'Activated Window': " + objWord.ActiveDocument.Name)
'Debug.Print ("selectionToPaste = " + selectionToPaste)
objWord.Selection.Paste
objWord.Documents(1).Activate
**iLoopCounter = iLoopCounter + 1**
objSelection.Find.Execute
Else
objWord.ActiveDocument.Save
objWord.ActiveWindow.Close 'have to close for the hardcode on "...Documents(1)..." and 2 to work.
Exit Do
End If
Loop
Next
End With
End Sub