node uri regex not capturing capture groups - node.js

I know there are a billion regex questions on stackoverflow, but I can't understand why my uri matcher isn't working in node.
I have the following:
var uri = "file:tmp.db?mode=ro"
function parseuri2db(uri){
var regex = new RegExp("(?:file:)(.*)(?:\\?.*)");
let dbname = uri.match(regex)
return dbname
}
I'm trying to identify only the database name, which I expect to be:
After an uncaptured file: group
Before an optional ? + parameters to end of string.
While I'm using:
var regex1 = new RegExp("(?:file:)(.*)(?:\\?.*)");
I thought the answer was actually more like:
var regex2 = new RegExp("(?:file:)(.*)(?:\\??.*)");
With a 0 or 1 ? quantifier on the \\? literal. But the latter fails.
Anyway, my result is:
console.log(parseuri2db(conf.db_in.filename))
[ 'file:tmp.db?mode=ro',
'tmp.db',
index: 0,
input: 'file:tmp.db?mode=ro' ]
Which seems to be capturing the whole string in the first argument, rather than just the single capture group I asked for.
My questions are:
What am I doing wrong that I'm getting multiple captures?
How can I rephrase this to capture my capture groups with names?
I expected something like the following to work for (2):
function parseuri2db(uri){
// var regex = new RegExp("(?:file:)(.*)(?:\\?.*)");
// let dbname = uri.match(regex)
var regex = new RegExp("(?<protocol>file:)(?<fname>.*)(<params>\\?.*)");
let [, protocol, fname, params] = uri.match(regex)
return dbname
}
console.log(parseuri2db(conf.db_in.filename))
But:
SyntaxError: Invalid regular expression: /(?<protocol>file:)(?<fname>.*)(<params>\?.*)/: Invalid group
Update 1
Answer to my first question is that I needed to not capture the ? literal in the second capture group:
"(?:file:)([^?]*)(?:\\??.*)"

That particular node regex library does not support groups.

Related

How to compare filenames with difference in special character encoding?

I am working with a system that syncs files between two vendors. The tooling is written in Javascript and does a transformation on file names before sending it to the destination. I am trying to fix a bug in it that is failing to properly compare file names between the origin and destination.
The script uses the file name to check if it's on destination
For example:
The following file name contains a special character that has different encoding between source and destination.
source: Chinchón.jpg // hex code: ó
destination : Chinchón.jpg // hex code: 0xf3
The function that does the transformation is:
export const normalizeText = (text:string) => text
.normalize('NFC')
.replace(/\p{Diacritic}/gu, "")
.replace(/\u{2019}/gu, "'")
.replace(/\u{ff1a}/gu, ":")
.trim()
and the comparison is happening just like the following:
const array1 = ['Chinchón.jpg'];
console.log(array1.includes('Chinchón.jpg')); // false
Do I reverse the transformation before comparing? what's the best way to do that?
If i got your question right:
// prepare dictionary
const rawDictionary = ['Chinchón.jpg']
const dictionary = rawDictionary.map(x => normalizeText(x))
...
const rawComparant = 'Chinchón.jpg'
const comparant = normalizeText(rawComparant)
console.log(rawSources.includes(comparant))

Replace regex pattern in array of strings - Logstash

I'm trying to remove url prefix from urls Array in logstash using ruby:
The url looks like this: urlArray = ['https://www.google.com','https://www.bcc.com']
I tried to use other array and do something like:
urlArray.each{ |url| newUrlArray.push(url.gsub("(https?://)?(www\.)?","")) }
I also tried:
newUrlArray = urlArray.map{ |url| url.gsub("(https?://)?(www\.)?","") }
I think I miss here something with the gsub.
Thanks
I suggest to use slice and then capture the group you're interested in.
urlArray = [
"https://www.google.com",
"https://www.bcc.com",
"http://hello.com",
"www.world.com"
]
newUrlArray = []
pattern = /(https?:\/\/)?(www.)?(.*)/
urlArray.each{ |url| newUrlArray.push(url.slice(pattern, 3)) }
puts newUrlArray
# google.com
# bcc.com
# hello.com
# world.com

crypto.createHmac fail with string like "face_url":"https\/\/"'

I have a problem to verify a string create by crypto.createHmac with Node.js.
I made some test, first in PHP - everything is OK but I can't find the correct way todo this in Node.js:
PHP CODE:
$jsonData = '"face_url":"https:\/\/"';
echo($jsonData);
echo("\n");
$client_secret = 'kqm6FksaIT';
echo hash_hmac("sha256", $jsonData, $client_secret);
Result:
"face_url":"https:\/\/"
34a4eb09a639c9b80713158ae89e7e8311586e6e6d76e09967f4e42a24759b3e
With Node.js, I have a problem with the interpretation of the string:
var crypto = require('crypto');
var str = '"face_url":"https:\/\/"';
console.log(str);
//OK
var buf1 = crypto.createHmac('sha256','kqm6FksaIT').update(str);
var v = buf1.digest('hex');
console.log(v);
//END
RESULT:
"face_url":"https://"
eb502c4711a6d926eeec7830ff34e021ed62c91e574f383f6534fdd30857a907
=> FAIL.
As you can see, the interpretation of the string is different "face_url":"https:\/\/"** VS **"face_url":"https://"**
I have tried a lot of things, Buffer.From base64, utf8, JSON.stringify, JSON.parse but I can't find a solution.
If you try with another string like: '"face_url":"https"' it's OK Result is the same.
I try to validate the key received in a Netatmo POST packet who contain:
"face_url":"https:\/\/netatmocameraimage.blob.core
You can find an implementation of netatmo webhook in PHP here:
https://github.com/Netatmo/Netatmo-API-PHP/blob/master/Examples/Webhook_Server_Example.php
After reflexion, the only difference between codes was the interpretation of request.body.
In PHP, it seems to be in plain text.
Nodejs parses the request in JSON format ...
After that supposition, i made some test with NodeJS this morning, i configured the expres server with the following option:
var express = require('express');
var crypto = require('crypto');
var app = express();
var bodyParser = require('body-parser');
app.use(bodyParser.text({type:"*/*"}));
After that, the string appears correctly with these famous "/" :
console.log RESULT :
,"face_url":"https://netatmocameraimage.blob.core.windows.net/production/
And voila! The HMAC is now CORRECT!
The HMAC from NETATMO is calculated on brut text and not from JSON!
In the PHP code, only the escape sequences \\ and \' are recognized in a single quoted expression, in all other cases the backslash is interpreted as a literal backslash, i.e. \/ is interpreted as a literal backslash followed by a literal slash (see here, sec. Single quoted). This explains the output of the PHP code:
$jsonData = '"face_url":"https:\/\/"';
...
Output:
"face_url":"https:\/\/"
34a4eb09a639c9b80713158ae89e7e8311586e6e6d76e09967f4e42a24759b3e
In JavaScript, the backslash is ignored for characters that do not represent an escape sequence, (see here, last passage), i.e. an \/ is equivalent to a literal slash. This explains the output of the JavaScript code:
var str = '"face_url":"https:\/\/"';
...
Output:
"face_url":"https://"
eb502c4711a6d926eeec7830ff34e021ed62c91e574f383f6534fdd30857a907
So in order for the JavaScript code to give the same result as the PHP, the backslash must be masked:
var str = '"face_url":"https:\\/\\/"';
...
Output:
"face_url":"https:\/\/"
34a4eb09a639c9b80713158ae89e7e8311586e6e6d76e09967f4e42a24759b3e
Presumably the string with the \/ is the result of a JSON serialization in PHP with json_encode(), which escapes the / by default, i.e. converts it to \/, see also here. In JavaScript, / is simply serialized as /. Note that in PHP the escaping of / can be disabled with JSON_UNESCAPED_SLASHES, see also here.

How is the context treated?

I have a weird behaviour on Core Data with my App. I have an App where user can create their own words entries with translation. When deleting all my Core Data I checked the nb of item and it was 0. When adding later 4 items the nb of items was 5?? I found the issue after a lot of tests and it seems not consistent for me: the issue was with this code:
fileprivate func duplicateCheckAndImport() {
// Check for duplicates
do {
self.words = try context.fetch(Word.fetchRequest()) // grab all Words
let nbOfWords = words!.count
print ("The nb of words in duplicateCheck...: \(nbOfWords ?? 0)")
}
catch {
// error message to add
}
let newWord = Word(context: self.context)
do {
self.words = try context.fetch(Word.fetchRequest()) // grab all Words
let nbOfWords = words!.count
print ("The nb of words in duplicateCheck...: \(nbOfWords ?? 0)")
}
catch {
// error message to add
}
the result of the 2 prints is 0 for the first grab and 1 for the 2nd grab which means that just this line of code -> let newWord = Word(context: self.context) adds an entry in Core Data but my purpose was just to take the context add words later on like this:
let newWord = Word(context: self.context)
newWord.name = item.name.trimmingCharacters(in: .whitespaces)
newWord.definition = item.definition.trimmingCharacters(in: .whitespaces)
Can someone explain me?
The line of code you mention
let newWord = Word(context: self.context)
...creates a new instance. That's what Word(context: self.context) does-- it says, create a new instance of Word using the context that you pass in.
From the code you provide, it's hard to tell exactly what you're trying to do that would not create a new instance. Your variable is called newWord, which suggests that you do mean to create a new Word, and that's what's happening.
Update: If you don't want the new instance, you can delete it just like any other managed object. So if you don't want newWord, you can
context.delete(newWord)
And then save changes. There are other ways to do this, but this is the simplest.

NodeSchool IO Exercies 3

I've started learning node.js
I'm currently on exercise 3, where we have to, based on a file buffer, calculate the number of new line characters "\n"
I pass the tester but somehow if I create my own file file.txt, I am able to get the buffer, and print out the string, but it is unable to calculate the number of new lines (console.log(newLineNum)) returns 0
Here is the code
//import file system module
var fs = require("fs");
//get the buffer object based on argv[2]
var buf = fs.readFileSync(process.argv[2]);
//convert buffer to string
var str_buff = buf.toString();
//length of str_buff
var str_length = str_buff.length;
var numNewLines = 0;
for (var i = 0; i < str_length; i ++)
{
if(str_buff.charAt(i) == '\n')
{
numNewLines++;
}
}
console.log(numNewLines);
If i understand your question correctly, you are trying to get the line length of current file.
From the documentation:
The first element will be 'node', the second element will be the name
of the JavaScript file.
So you should replace process.argv[2] with process.argv[1].
Edit:
If you are passing a parameter for a file name on command-line like:
node server.py 'test.txt'
your code should work without any problem.
Your code is fine. You should check the file that you are using for the input.

Resources