Refactoring regular expression needed - regex

Can you please help me with a regular expression that I need for some code refactoring? I am trying to change the following
something a.executeQuery() something else
something b.executeQuery() something else
something c.executeQuery() something else
to
something someClass.executeQueryEx(a) something else
something someClass.executeQueryEx(b) something else
something someClass.executeQueryEx(c) something else
Basically trying to bring all DB calls to a central function, so that I can log them and do error handling at one place.

Assuming a,b,c are just identifiers, you can simply replace
(\w+)\.executeQuery\(\)
with
someClass.executeQueryEx(\1)
or
someClass.executeQueryEx($1)
depending on your regex engine.
If they can be arbitrary expressions, as in foo(quux).bar[25].executeQuery() I don't think you can do that with regexes alone.

Related

Regex-Match while ignoring a char from Searchword

I am using an Engineering Program which lets me Code formulas in order to filter out specific lines in a database. I am trying to look for a certain line in the database which contains e.g. "concrete" as a property.
In the Code I can use regular expressions.
The regex I was using so far looked like this:
".*(concrete).*";
so if the line in the database contains concrete, I will get the wanted result.
Now the Problem is: i would like to switch the word concrete with a variable, so that it Looks like this:
".*(#VARIABLE1).*";
(the Syntax with the # works in the program btw.)
the Problem is: if i set the variable as concrete, the program automatically switches it for 'concrete' . Obviously, the word concrete cant be found anymore, since the searchterm now contains the two ' Symbols in the beginning and i the end.
Is there a way to ignore those two characters using the Right regex?
what I want it to do is the following:
If a line in the database contains "25cm concrete in Grey"
I should get a match from the regex.
with the searchterm ".*(concrete).*"; it works, with the variable ".*(#VARIABLE1).*"; it doesnt.
EDIT:
the whole "Formula" in the program Looks like that:
if(Match(QTO(Typ:="Attribut{FloorsLayer_02_MaterialName}");".*(#V_QUALITY).*" ;"regex") ;QTO(Typ:="Attribut{Fläche}");0)
I want the if-condition to be true, when the match inside is true.
the whole QTO function is just the programs Syntax to use a certain Attribute into the match-function, the middle part is my Problem. I really don't know the programming language or anything,I'm new to this. hope it helps!
Thats more of a hack than a real solution and i'm not sure if it even works:
if you use the regex
.*(#VARIABLE1)?).*
and the string ?concrete(
this will result in a regex looking like this:
.*('?concrete(')?).*
which makes the additional characters optional.
This uses the following assumtption:
the string (#VARIABLE1) gets replaced by the ('<content of VARIABLE1>')

Evaluating multiple expression using th:if in Thymeleaf

I am wondering what the correct syntax for multiple expressions within th:if in Thymeleaf is.
So far I have something like this:
<a style="color:blue" th:href="#{/approveAndJoin/{name}(name=${outbox.receiverName})}" th:if="${not #strings.startsWith(outbox.status, 'P')}">Join Team?!</a>
What would the correct syntax be to do something like this:
(Pseudo code)
th:if="${not #strings.startsWith(outbox.status, 'P') && #strings.startsWith(inbox.status, 'A'}"
I have read through the various manuals but have not discovered how to do this.
You can combine several conditions with the keyword and
e.g. in your case th:if="${not #strings.startsWith(outbox.status, 'P') and #strings.startsWith(inbox.status, 'A'}"

Notepad++ Find/Replace Wildcard problems

Hopefully this is simple because I can't seem to figure it out.
I have a game that outputs a log with information I'd like to review, but it's bogged with tags.
<color=#9B9B9BFF>abndnd_b9o66v</color>.<color=#1EFF00FF>out_ys0a67</color>
<color=#9B9B9BFF>uknown_ospiw8</color>.<color=#1EFF00FF>p_vyuxzb</color>
<color=#9B9B9BFF>anonymous_yzgoqq</color>.<color=#1EFF00FF>pub_info_o1rotu</color>
<color=#9B9B9BFF>unidentified_t7stef</color>.<color=#1EFF00FF>out_gems04</color>
<color=#9B9B9BFF>abndnd_5vs06o</color>.<color=#1EFF00FF>public_7gshh2</color>
<color=#9B9B9BFF>anon_7kq2k4</color>.<color=#1EFF00FF>pub_wxn46t</color>
<color=#9B9B9BFF>anon_i83kkg</color>.<color=#1EFF00FF>info_ev39gs</color>
I can simply filter it by hand, but I know a regex may be able to help, I just can't seem to figure out the syntax correctly and how to trim the tags without tampering with the needed text
and my end result I'm trying to get is this:
abndnd_b9o66v.out_ys0a67
uknown_ospiw8.p_vyuxzb
anonymous_yzgoqq.pub_info_o1rotu
unidentified_t7stef.out_gems04
abndnd_5vs06o.public_7gshh2
anon_7kq2k4.pub_wxn46t
anon_i83kkg.info_ev39gs
Try this:
<color=.*?>(.*?)</color>\.<color=.*?>(.*?)</color>
Replace by this:
\1\.\2

vim abbreviations and regular expressions

In vim, is it possible to use regular expressions in abbreviations? For example, something like
:iab \([0-9]\{-}\)nm \\SI{\1}{\\nano\\meter}
would would expand every instance of, say, '50nm' to '\SI{50}{\nano\meter}'.
Your best bet is to write a little helper function to yourself. Tapping into omni completion or the user defined completion (C-x C-u, see :help 'cfu') is a good choice. I sketched a regular function to imap on a key:
function! ExpandNanometers()
let items = matchlist(expand('<cword>'), '\v(\d+)nm')
if len(items) == 0
return
endif
let modified = '\SI{' . items[1] . '}{\nano\meter}'
exec "normal! ciw" . modified
endf
imap <C-l> <C-o>:call ExpandNanometers()<CR>
Not the best code, perhaps. Bound on insert-mode C-l, it will replace words such as 50nm to the desired if the cursor is on the word or directly after it.
I wanted to add this as a comment to the previous answer, but apparently I can't until 50 rep. I also know this is wayyy too late, but for reference purposes:
If key mappings are acceptable (going by the prev. answer), surely something like
imap <silent> <leader>obscure-key-of-choice <Esc>:%s/\v(\d+)nm/\\SI{\1}{\\nano\\meter}/g<CR>``i
(i.e. global substitute on the whole file with the desired patterns)
would be easier to maintain? I like to avoid vimscript for readability/maintenance of the .vimrc! Obviously you replace obscure-key-of-choice by your obscure key of choice. You only have to do it once after having typed all the text anyway, so better save the other keys for more conventionally useful bindings!
The shortcut replaces something like
50nm blabla 73nm your-interesting-science-here 89nm
... some new lines...
we love nanometers nm! 34nm and finally 18nm
with something like
\SI{50}{\nano\meter} blabla \SI{73}{\nano\meter} your-interesting-science-here \SI{89}{\nano\meter}
... some new lines...
we love nanometers nm! \SI{34}{\nano\meter} and finally \SI{18}{\nano\meter}

How to replace strings in a code

I want to perform a batch replace operation on a project by following some rules. For e.g. I am taking notes in the code like this:
On every code piece, which is commented like this, I want to perform a replace operation, which will replace the input code piece with the output code piece in the following examples:
Input 1:
//+
a++;
//+(+SomeException$SomeMessage)
Output 1:
try
{
a++;
}
catch (AnException)
{
throw;
}
catch (Exception ex)
{
throw new SomeException("SomeMessage", "15", ex);
}
Input 2:
//+
a++;
//-(+InvalidOperationException$SomeMessage)
Output 2:
try
{
a++;
}
catch (InvalidOperationException ex)
{
throw new AnException("SomeMessage", "16", ex);
}
Input 3:
//+
a++;
//-(SomeMessage)
Output 3:
try
{
a++;
}
catch (Exception ex)
{
throw new AnException("SomeMessage", "17", ex);
}
The magic numbers (15, 16, 17) will increase for each code piece commented like this. I know this is not the best practice but I am not making the decisions and I am expected to handle exceptions like this, so I thought I can ease the pain by taking notes and batch replacing in the end. What is the best way to do this? Should I write my own code to perform replaces or is there some regex replace tool or something like that exist that can automatically make this for me?
Update: This is a one time job and my magic number has to be globally unique. So if it was 25 for the last match in a file, it must be 26 for the first match in the next file.
What is the best way to do this? Should I write my own code to perform replaces or is there some regex replace tool or something like that exist that can automatically make this for me?
I'd write a little program in C++ or C# to do this. There are presumably other tools and script languages that can do it; but given that it's a trivial job in C++ or C# and given that I aready know how to do it in these languages, why not?
I don't know what you mean by the "best" way, but for me at least this would be one of the easiest ways.
This looks like a simple language that you're going to compile into another language that looks like Java. A compiler is the right tool for a job like this, especially because you need to keep around the state of the current magic number. It also seems likely that whoever is making the decisions would want to add new features to the language, in which case a solution glued together with regular expressions might not work properly.
If I'm right about what you really want, your question is reduced to the problem of "How do I write a Domain Specific Language?" I'm not sure what the best method would be for this, but if you know Perl you could probably put together a solution with Parse::RecDescent.
I think it's possibly to do this with scripting and regular expressions, but this is the type of problem for which compilers were invented. If you end up making something hacky, God help the person that has to maintain it after you! :)
You could write a CodeSmith template that reads that input and outputs that output. But, I'm not sure you could do it in-line. That is, you would need a file of just inputs and then your template could give you the file of outputs. I'm not sure if that acceptable tho.
There's a lot of ways you could do this, even though you probably shouldn't (as you seem to realize, this will just result in meaningless exceptions). Nevertheless, here's a sed/sh combo to do the first one. It doesn't handle the autonumbering or your other variants. I'll leave that as an exercise for the OP.
P1='\/\/+'; P2='\(.*\)'; P3='\/\/+(+\([^$]*\)$\(.*\))';
echo 'foo()\n//+\na++\n//+(+SomeException$Message)'|sed ' /'$P1'/ { N; /'$P2'/ { N; /'$P3'/ { s/'$P1'\n'$P2'\n'$P3'/try\n{\n\t\1\n}\ncatch (AnException)\n{\n\tthrow;\n}\ncatch (Exception ex)\n{\n\tthrow new \2("\3", "0", ex);\n}/ } } } '
The echo is just a test string.
As an Emacs user, for a one time job I'd do this by defining keyboard macros,
then use set/increment/insert-register for the autonumbering magic. There
shouldn't really be any need for writing your own elisp functions.
Though if you need to perform this on more than just a couple of files, you'll
probably be better off writing a script to do the job.
If you do not happen to use an IDE like Emacs (as answered by many) with strong regex support I would write a little script. Note that text manipulation is in general more a scripting operation, e.g. Perl, Ruby, due to regex support in the language itself. On the other hand if you are very familiar with say Java Pattern, then writing it in Java is propably the fastest solution, even if you need more overhead esp. for a one time operation.
So a litte Ruby script might look like that (beware, I did not test it):
$cnt = 1
IO.readlines(filename).collect { |line|
if line =~ /^\s*\/\/\+\s*$/
$cnt += 1
["try\n", "{\n" ]
elsif line =~ /^\s*\/\/\+\(\+(.+)\$(.+)\)\s*/
["}\n", "catch (#{$1} ex)\n", "{\n",
"throw new AnException(\"#{$2}\", \"#{$cnt}\", ex);\n", "}\n"]
# propably more else for all cases
else
line
end
}.flatten
# save the file again