replace with actual word in ruby - ruby

I have the following string.
x = %q{ On the server side, my EJB3 application uses Spring for configuring all sorts of things. So my EJBs all look up various ApplicationContexts and use them as a sort of...well, I was going to say poor man's JNDI, but the reality is that JNDI in the J2EE environment is really a poor man's Spring. :-)
On the GUI side, I use it instead of resource injection to get access to my EJBs. That lets me test the GUI component with simple pojos. So ejb is very good technology}
I am replacing the string "ejb", case insensitive. I am doing this:
y = x.gsub(/(ejb)/i, '<em>EJB</em>')
# => " On the server side, my <em>EJB</em>3 application uses Spring for configuring all sorts of things. So my <em>EJB</em>s all look up various ApplicationContexts and use them as a sort of...well, I was going to say poor man's JNDI, but the reality is that JNDI in the J2EE environment is really a poor man's Spring. :-)\n\nOn the GUI side, I use it instead of resource injection to get access to my <em>EJB</em>s. That lets me test the GUI component with simple pojos. So <em>EJB</em> is very good technology"
I have a match in lower case: "ejb", and I am replacing with this: "<em>EJB</em>". How can I replace it without case change? I want "<em>ejb</em>".

x.gsub(/(ejb)/i, '<em>\1</em>')

You want:
gsub(/(ejb)/i, "<em>#{$1}</em>")

'test EjB123'.gsub(/ejb/i, "<em>#{$1}</em>")
=> "test <em>EjB</em>123"

You might want to try:
x.gsub!(/(ejb)/i) {|m| "<em>#{$~}<em>"}
There are a set of Special global variables set by the Pattern matching:
$~ is equivalent to ::last_match;
$& contains the complete matched text;
$` contains string before match;
$' contains string after match;
$1, $2 and so on contain text matching first, second, etc capture group;
$+ contains last capture group.
For more info:
Ruby Regex

Related

Sort a property in HCL Block

I would like to move name property to the top of the block like this.
There are many resouce block in a file.
Before
resource "datadog_monitor" "A" {
enable_logs_sample = "true"
name = "name"
tags = ["env:dev"]
}
resource "datadog_monitor" "B" {
enable_logs_sample = "true"
name = "name"
tags = ["env:dev"]
}
After
resource "datadog_monitor" "A" {
name = "name"
enable_logs_sample = "true"
tags = ["env:dev"]
}
resource "datadog_monitor" "B" {
name = "name"
enable_logs_sample = "true"
tags = ["env:dev"]
}
OK, I think :help :global and the range/address mechanism is one of Vim's best and most underrated feature so it might deserve a detailed run down.
The core editing pattern is the same as in the commands I suggested in my previous answer to a similar question of yours:
on each line matching a specific regular expression pattern,
do something.
Note that it is a "pattern", not a one-off trick. You are not supposed to "learn" this answer by heart, or commit it to "muscle memory", or bookmark it for the next time you have the exact same problem. Instead, you are supposed to grok the logic behind it in a way that allows you to:
recognize a situation where it might come handy,
apply it without too much thinking.
So, in order to implement the editing pattern described above, we use the :global command, which works like this:
:[range]global/<pattern>/[range]<command>
where:
in range (optional, default is %),
mark each line matching <pattern>,
then execute <command> on range (optional, default is .).
Like lots of things in Vim, :global is conceptually cool but not necessarily useful on its own. The more familiar you are with ranges/addresses and the more Ex commands you know, the more useful it is.
In this specific case, ranges don't matter much but addresses and Ex commands do… and their sum makes problems like these solvable in, IMO, a pretty intuitive way.
Now, let's go back to our problem:
move every "name" line to the top of the block
and express it in terms that match our editing pattern:
mark every line matching name,
then move it below the closest line above matching resource.
Which is a simple:
:g/name/m?resource?
Of course, the exact regular expression patterns to use are context-dependent.
The trick is to internalize the patterns so that you already know how to use any new building block you might come upon.
There is really nothing even remotely god-like, here.

How to convert a collection in config to environment variable in Microprofile/Quarkus/Smallrye

We are running our apps in a K8 Cluster and rely on the configuration by environment variables. For the conversion of application.properties/application.yaml parameters in Quarkus, the following conversion rules apply: https://github.com/eclipse/microprofile-config/blob/master/spec/src/main/asciidoc/configsources.asciidoc#default-configsources
In this rule it is not mentioned how to convert collections.
Let's say I have the following config:
server.environments[0].name=dev
server.environments[0].apps[0].name=rest
server.environments[0].apps[0].services=bookstore,registration
server.environments[0].apps[0].databases=pg,h2
server.environments[0].apps[1].name=batch
server.environments[0].apps[1].services=stock,warehouse
How would I convert it to an environment variable?
I've tried the following:
SERVER_ENVIRONMENT_0_APPS_0_DATABASES
SERVER_ENVIRONMENT[0]_APPS[0]_DATABASES
No chance to make it work. Does anyone know how to do this? Is this supported anyway?
You were pretty close, just follow the rules mentioned in the docu:
Replace each character that is neither alphanumeric nor _ with _; then convert the name to upper case (i.e. COM_ACME_SIZE)
So given we have a config property named server.environments[0].apps[0].name when you replace each non-alfanumeric character with _ and convert to upper case you end up with: SERVER_ENVIRONMENTS_0__APPS_0__NAME. Note the double underscore between 0 and APPS as you substitute both . and [ for _.
That will certainly not win any prize for the prettiest env var name but it does the job :).
You can check how exactly it is done in the Smallrye implementation of MP config - which is the implementation used by Quarkus.

How to load value from dynamically specified parameter in NiFi

I have several processes with almost same flow like "Get some parameters, extract data from database according to them and upload them to target". The parameters vary slightly across processes as well as targets but only a bit. Most of the process is the same. I would like to extract those differences to parameter-context and dynamically load them. My idea is to have parameters defined following way and then using them.
So core of question is:
How to dynamically choose which parameter group load and use?
Having several parameter contexts with same-named/different-valued parameters and dynamically switching them would be probably the best, but it is not possible as far as I know.
Also duplicating flows is out-of-the-table. Any error correction would be spread out over several places and maintenance would be a nightmare.
Moreover, I know I can do it like "In GenetrateFlowFile for process A set value1=#{A_value1} and in GenetrateFlowFile for process B set value1=#{B_value1}. But this is tedious, error-prone and scales kinda bad. Not speaking of situation when I can have dozens of parameters and several processes. Also it is a kind of hardcoding, not configuring...
I was hoping for something like defining group=A and then using it like value1=#{ ${ group:append('_value1') } } but this does not work - it is evaluated as parameter literally named ${ group:append('_value1') }.
TL;DR: Use evaluateELString().
The actual solution is to set in GenetrateFlowFile processor group=A and in next UpdateAttribute processor set the following:
value1=${ group:prepend('hash{ '):append('_value1 }'):replace('hash', '#'):evaluateELString() }
The magic being done here is "Take value of group slap around it #{ and _value1 } to make it valid NiFi Expression Language statement and then evaluate it." (Notice - the word hash and function replace is there since I didn´t manage to escape the # char right before {.)
If you would like to have your value1 at the beginning of the statement then you can use following code. The result is same, it is easier to use (often-changed value value1 is at the beginning of the statement) and is less readable "what is really going on?"-wise.
value1=${ literal('value1'):prepend('_'):prepend(${ group }):prepend('hash{ '):append(' }'):replace('hash', '#'):evaluateELString() }

Spring SpEL escape package name in T() function

I have simple question, Is it possible to escape package name in Spring-EL function T(..)?
The reason why I need this is because I live in Lithuania and all our packages start with country code lt f.e. lt.aaa.bbb.ccc. As you could expect this something we can not change.
Now, when I try to use SpEL to access some constant or static function in my classes I write:
#{T(lt.aaa.bbb.ccc).CONSTANR_VAR}, but this doesn't work, because SpEL parses expression and interprets lt as 'Less Then' not as part of package. This should be a problem for country codes gt, eq etc.
Is there any way around this, or are we just wery unlucky?
I can't immediately think of a workaround. I created:
https://jira.springsource.org/browse/SPR-10942
against the spring framework to cover the problem. I have SpEL open up at the moment as I'm working on something so I might try to get this fixed soon.

how to replace a string in a ruby file after a match is found

I have a xml file, which i need to modify from my ruby script and save it. xml file looks something like
`
<mtn:messages>
<mtn:message correlation-key="0x" sequence="4">
<mtn:header>
<mtn:protocol-version>0x4</mtn:protocol-version>
<mtn:message-type>0x0F04</mtn:message-type>
<mtn:ttl>4</mtn:ttl>
<mtn:qos-class-of-service>0</mtn:qos-class-of-service>
<mtn:qos-priority>2</mtn:qos-priority>
</mtn:header>
</mtn:message>
</mtn:messages>
</mtn:test-case>
<mtn:test-case title="Train-Consist-Message">
<mtn:messages>
<mtn:message correlation-key="0x" sequence="4">
<mtn:header>
<mtn:protocol-version>0x4</mtn:protocol-version>
<mtn:message-type>0x0F04</mtn:message-type>
<mtn:ttl>4</mtn:ttl>
<mtn:qos-class-of-service>0</mtn:qos-class-of-service>
<mtn:qos-priority>2</mtn:qos-priority>
</mtn:header>
</mtn:message>
</mtn:messages>
</mtn:test-case>`
I need to replace <mtn:ttl>4</mtn:ttl> with <mtn:ttl>some other value</mtn:ttl> which comes under <mtn:test-case title="Train-Consist-Message"> and save it.
I have written below code, but its replacing all occurances of <mtn:ttl>4</mtn:ttl>.
`doc = IO.read(ENV['CadPath1']+ "conf\\cad-mtn-config.xml")
doc.gsub!(pattern, str)
File.open("File path", "w"){|fh| fh.write(doc)}`
Please help me with this. Waiting for your early reply...
String#gsub! modifies the string in-place, replacing all instances with the replacement specified. If you only want to replace the first instance, use String#sub or String.sub!.
The suggestion from Mike about using sub instead of gsub is good. But parsing XML (and HTML) with regular expression is usually frowned upon.
From your question I assume that you locate the to-be-modified element in terms of parent-child relations, not in terms of the source code order (i.e. you will not be able to say: "modify the second occurrence of this pattern"), so inventing a reliable regular expressions may be very, very hard.
You should use a parser library to find the element you want to change. There is a pretty large collection of those. See some of them at http://ruby-toolbox.com/categories/html_parsing.html and pick one, or use a built-in REXML library.
Alternatively, you could use a very simple 'html-scanner' module, which is included in Rails' ActionController (action_controller/vendor/html-scanner.rb), but if you do not use Rails, I am not sure whether extracting it is worth your time.
The exact code will depend on the parser you choose. Usually they have pretty good documentation/tutorials, so I am sure you will be able to handle it.

Resources