Vi regular expression - regex

Looking to perform a find and replace on the following string:
"_id" : { "$oid" : "52853800bb1177ca391c17ff" }, "Ticker" : "A", "Profit Margin" : 0.137, "Institutional Ownership" : 0.847, "EPS growth past 5 years" : 0.158, "Total Debt/Equity" : 0.5600000000000001, "CurrentRatio" : 3, "Return on Assets" : 0.089, "Sector" : "Healthcare", "P/S" : 2.54, "Change from Open" : -0.0148, "Performance (YTD)" : 0.2605, "Performance (Week)" : 0.0031, "Quick Ratio" : 2.3, "Insider Transactions" : -0.1352, "P/B" : 3.63, "EPS growth quarter over quarter" : -0.29, "Payout Ratio" : 0.162, "Performance (Quarter)" : 0.09279999999999999, "Forward P/E" : 16.11, "P/E" : 19.1, "200-Day Simple Moving Average" : 0.1062, "Shares Outstanding" : 339, "Earnings Date" : { "$date" : 1384464600000 }, "52-Week High" : -0.0544, "P/Cash" : 7.45, "Change" : -0.0148, "Analyst Recom" : 1.6, "Volatility (Week)" : 0.0177, "Country" : "USA", "Return on Equity" : 0.182, "50-Day Low" : 0.0728, "Price" : 50.44, "50-Day High" : -0.0544, "Return on Investment" : 0.163, "Shares Float" : 330.21, "Dividend Yield" : 0.0094, "EPS growth test years" : 0.13 }
Specifically, I want to find all characters in quotations and remove any whitespaces found. i.e. "Profit Margin" becomes "ProfitMargin", "Institutional Ownership" becomes "InstitutionalOwnership" etc. I'd like to do this in Vi.
Thanks for the help in advance!

A possible answer:
:%s/\("[^"]*"\)/\=substitute(submatch(1), " ", "", "g")/g
And the way I got it:
Search what we want to replace => /".*" (quote symbol + n times whatever + quote symbol)
Do it properly => /"[^"]*" (quote symbol + n times whatever is not a quote symbol + quote symbol)
Transform that into a substitution that does nothing => :%s/\("[^"]*"\)/\1/g
Check :help :%s, from there :help sub-replace-special.
Use the magic \= learned before, still doing nothing => :%s/\("[^"]*"\)/\=submatch(1)/g
Replace \=submatch(1) by something useful => :%s/\("[^"]*"\)/\=substitute(submatch(1), " ", "", "g")/g (:help substitute).

Related

How to query with conditionals in MongoDB

I am new to MongoDB and am learning how to query for multiple things at once with conditionals.
I have a database with a document called 'towns' that contains an id, name, population, date of last census, items it is famous for, and mayor. For example, this is what one of the towns looks like (please keep in mind, this is old, random data, nothing is up to date, it is just an example for me to learn):
{
"_id" : ObjectId("60232b0bbae1e5336c5ebc96"),
"name" : "New York",
"population" : 22200000,
"lastCensus" : ISODate("2016-07-05T00:00:00Z"),
"famousFor" : [
"the MOMA",
"food"
],
"mayor" : {
"name" : "Bill de Blasio",
"party" : "D"
}
I am trying to find all towns with names that contain an e and that are famous for food or beer.
I currently have this query:
db.towns.find({name: {$regex:"e"}}, {$or: [{famousFor:{$regex: 'food'}}, {famousFor:{$regex: 'beer'}}]})
If I split up the name and the $or expression, it works, but together I get errors like:
Error: error: {
"ok" : 0,
"errmsg" : "Unrecognized expression '$regex'",
"code" : 168,
"codeName" : "InvalidPipelineOperator"
Or, if I switch the query to db.towns.find({name:/e/}, {$or: [{famousFor:/food/}, {famousFor:/beer/}]}) I get the error:
Error: error: {
"ok" : 0,
"errmsg" : "FieldPath field names may not start with '$'.",
"code" : 16410,
"codeName" : "Location16410"
What am I doing wrong? Is it how I am structuring the query?
Thanks in advance!
Problem Is the syntax.
find({condition goes here}, {projection goes here})
You need to put all of your conditions within one curly brace.
db.towns.find({name: {$regex:"e"}, $or: [{famousFor:{$regex: 'food'}}, {famousFor:{$regex: 'beer'}}]})

Regex to find string between patterns not containing specific string

Ok gurus,
Lets say I have the following string:
{
"event" : "party" ,
"Id" : "store" ,
"timestamp" : "2019-07-07T13:14:26.329Z" ,
"localDateTime" : "2019-07-07T16:14" ,
"orderStateUpdate" : {
"id" : "fj09bA9ywfGS" ,
"orderId" : "2315043" ,
"visitId" : "2315043" ,
"items" :{{
"id" : "fj09bA6K3K8u" ,
"quantity" : 1 ,
"stat" : "ok"
},
{
"id" : "fj09bA6K3K8u2" ,
"quantity" : 2 ,
"stat" : "ok"
}}
,
"items" :{{
"id" : "fj09bA6K3K8u" ,
"quantity" : 1 ,
"stat" : "junk"
},
{
"id" : "fj09bA6K3K8u2" ,
"quantity" : 2 ,
"stat" : "ok"
}}
,
"extraParams" : {"extraparamstuff1":"bugger"},"somethingelse" :"blahblahblah"
}}
The string has two (nested arrays) wrapped by double curly braces. This string specifically contains an error where the LAST curly brace is ALSO double; what I am trying to capture with regex is the string that starts with '}}' , ends with '}}' and DOES NOT CONTAIN '{{' like so:
}}
,
"extraParams" : {"extraparamstuff1":"bugger"},"conversationLink" :"https://qa.app.package.ai/qa/#/app/dashboard?d=1561248000000&c=fdxkID9IifGv&p=fdxfaFgV1l1Y"
}}
I am Regex-challenged, but have come up with this:
(?:(\}\})).*(?:\{\{).*(?:\}\s*?\})
which captures
}}
,
"items" :{{
"id" : "fj09bA6K3K8u" ,
"quantity" : 1 ,
"itemState" : "LOADED"
},
{
"id" : "fj09bA6K3K8u2" ,
"quantity" : 2 ,
"itemState" : "LOADED2"
}}
,
"extraParams" : {"extraparamstuff1":"bugger"},"conversationLink" :"https://qa.app.package.ai/qa/#/app/dashboard?d=1561248000000&c=fdxkID9IifGv&p=fdxfaFgV1l1Y"
}}
which is too much. Can someone help me understand how to find this? This is for error-checking inbound data (and yes I need to check for extra opening '{{' as well).
Okay, so, I think you need a negative lookahead since you have to accept curly braces, but not doubles... this is what I've come up with, not sure if it will work in every case though.
}}([^{]|{(?!{))+}}
It basically says: look for two closing curlies (}}), then either any non-opening curly character ([^{]) OR a single opening curly character (using negative lookahead) ({(?!{)), repeat that as many times as needed (+), and finish with a double closing curly (}})
Link to live (updateable) demo: https://regex101.com/r/kwlzco/2

how to add special characters in mongo $regex

I want to look for "\r" in a string field I have in mongo, and I fount this, which looks like it works good:
db.users.findOne({"username" : {$regex : ".*son.*"}});
the problem is that i want to look for "\r" and I can find it, which I know its there, so I just did:
db.users.findOne({"username" : {$regex : ".*\r.*"}});
and it dosent work, how can I fix this?
example document:
{
"personId" : 1,
"personName" : "john",
"address" : {
"city" : "Rue Neuve 2\\r\\rue Pré-du-Mar \\r ché 1 1003 Lausanne",
"street" : "",
"zipCode" : "",
"streetNumber" : ""
}
}
so my query is:
db.users.findOne({"address.city" : {$regex : ".*\r.*"}});
also tried:
db.users.findOne({"address.city" : {$regex : ".*\\r.*"}});
try
db.users.findOne({"username" : {$regex : ".*\\r.*"}});
I think your issue is that you have your .* backwards at the end. You are looking for a "2." literal followed by any characters as opposed to what you have at the beginning, .*, saying anything before the literal that isn't a carriage return. Try to change this to
db.users.findOne({"username" : {$regex : ".*\\r*."}});
Which says give me "\r" with any non carriage return characters before the literal and any non carriage return characters after the literal.
I found that the way to do it is:
db.users.findOne({"username" : {$regex : ".*\\\\.*"}});

How to parse txt-file using REGEXP_SUBSTR in oracle?

I have got a lot of txt cards with same format.
And I need parse it to get some values from them.
I don't understand how use regexp substr in Oracle. Please, Help me write sql statements, which return values, which I marked between **-symbols (for example: first string, 02/02/11, AA11223344 and etc):
From: "abc def (**first string**)" <email#site.com>
02/01/2011 09:27 First Date : **02/02/11**
Player : BILL BROWN ID : **AA11223344**
At : YELLOW STREET. CD Number : **A11223FER**
Code :
BUYS : **123M** (M) of AAA 0 02/02/11 Owner : **England**
Shiped : **02/04/11**
Number : **11.223344** Digi : **1.2370000**
Ddate: **02/04/11**
Notes : **First line here**
* Size : **USD 11,222,333.44**
* Own ( **0 days** ): **0.00**
* Total : USD **222,333,444.55**
You can recursively apply regexp evaluation by using hierarchical queries; at each level, you look for the level-th occurrence in your string.
Please pay attention to the "non greedy" operator (??) in pattern string, explained here, as well as regular expression functions.
with test as (
select 'From: "abc def (**first string**)" <email#site.com>
02/01/2011 09:27 First Date : **02/02/11**
Player : BILL BROWN ID : **AA11223344**
At : YELLOW STREET. CD Number : **A11223FER**
Code :
BUYS : **123M** (M) of AAA 0 02/02/11 Owner : **England**
Shiped : **02/04/11**
Number : **11.223344** Digi : **1.2370000**
Ddate: **02/04/11**
Notes : **First line here**
* Size : **USD 11,222,333.44**
* Own ( **0 days** ): **0.00**
* Total : USD **222,333,444.55** ' as txt
from dual
)
select TRIM('*' FROM regexp_substr(txt, '\*\*(.*??)\*\*', 1, LEVEL, 'n') )
from test
CONNECT BY regexp_subSTR(txt, '\*\*(.*??)\*\*', 1, LEVEL, 'n') is not null

SpringMongo Case insensitive search regex

I am trying a case insensitive search in Mongo. Basically I want case insensitive string match I am using regex. Here is my code
Query query = new Query( Criteria.where(propName).regex(value.toString(), "i"));
But the above dosent match my whole string(a string sometime with spaces). It returns values even if its a substring.
Eg: Suppose my collection has 2 values "Bill" and "Bill status',It returns me "bill" even if my search is "bill status". It returns results even if the there is a sub string of the string I am searching for
I tried Query query = new Query( Criteria.where(propName).is(value.toString()));
But the above is case sensitive. Can someone please help on this.
Insensitive search using regex search. input_location could be Delhi,delhi,DELHI, it works for all.
Criteria.where("location").regex( Pattern.compile(input_location, Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CASE)));
The regex /^bill$/i will match just against "Bill" in a case-insensitive manner.
Here is an example showing this (in the mongo shell):
> db.foo.insert({name: "Bill"});
> db.foo.insert({name: "Bill status"});
> db.foo.insert({name: "another Bill"});
> db.foo.find()
{ "_id" : ObjectId("5018e182a499db774b92bf25"), "name" : "Bill" }
{ "_id" : ObjectId("5018e191a499db774b92bf26"), "name" : "Bill status" }
{ "_id" : ObjectId("5018e19ba499db774b92bf27"), "name" : "another Bill" }
> db.foo.find({name: /bill/i})
{ "_id" : ObjectId("5018e182a499db774b92bf25"), "name" : "Bill" }
{ "_id" : ObjectId("5018e191a499db774b92bf26"), "name" : "Bill status" }
{ "_id" : ObjectId("5018e19ba499db774b92bf27"), "name" : "another Bill" }
> db.foo.find({name: /^bill$/i})
{ "_id" : ObjectId("5018e182a499db774b92bf25"), "name" : "Bill" }
However, a regex query will not use an index, except if it is left-rooted (ie. of the form /^prefix/) and if the i case-insensitive flag is not used. You may pay a substantial performance penalty over using a query that uses an index. As such, depending on your use case, a better alternative might be to use application logic in some way, for example:
Enforce a case when you insert items into the database (e.g. convert "bill" to "Bill").
Do a search against your known case (e.g. search just against "Bill").