I have a gulp.src on a task but I want to match all the files that contain a certain word as a prefix e.g.:
gulp.src('./mydir/project.build-blessed1.css')
But there can be N files with different numbers, blessed1, blessed2, blessed3
How can I make it match any file that starts with that and has the .css extension on the same line, without using a function?
if you're not using an old implemetation of gulp you can use '*' as wild card even in the middle of a path so something like:
gulp.src('./mydir/project.build-blessed*.css')
should work
You can see the doc here https://github.com/gulpjs/gulp/blob/master/docs/API.md
As Splatten suggested, you could use string.lastIndexOf method. In your case:
var string = 'i want to do something!'
if (string.lastIndexOf('something') !== -1) {
//keyword was found, meaning it's in the string
} else {
//keyword was not found
}
lastIndexOf returns the index where he found the keyword.
Related
I currently have a findFile function I use within a forEach Loop to iterate through an array of filenames and then provide a new array of the file system paths for each of the filenames within the original array:
var dir = 'Some File System Path';
const fs = require('fs');
const findFile = function (dir, pattern) {
var results = [];
fs.readdirSync(dir).forEach(function (dirInner) {
dirInner = path.resolve(dir, dirInner);
var stat = fs.statSync(dirInner);
if (stat.isDirectory()) {
results = results.concat(findFile(dirInner, pattern));
}
if (stat.isFile() && dirInner.endsWith(pattern)) {
results.push(dirInner);
}
});
return results;
};
var newFileArr = ['1.txt', 'file2.txt', 'file3.txt', 'file4.txt']
function fpArr(newFileArr) {
const fpArray = [];
newFileArr.forEach((file => {
fpArray.push(findFile(dir, file).toString())
//console.log(fpArray)
}));
OutPut:
[
/some/file/path/file1.txt,
/some/file/path/1.txt,
/some/file/path/file2.txt,
/some/file/path/file3.txt,
/some/file/path/file4.txt
]
The issue I am facing is my findFile looks for a pattern match and it picks up the path for "1.txt" presumably when it is searching for "file1.txt". I know this is an edge case, but it is an important edge case because other filenames may end with the same letters or numbers and I do not want those to be picked up in the file path array output. I have tried several ideas such as ".match()" and ".startsWith" however those will only work with a string literal or regEx as far as I can tell which causes the search itself to fail. I am looking to see if there is a way to get the findFile function to do an exact match based off a variable of some string value? Any help getting me in the right direction is appreciated.
[
'K_01.00.0000.iar',
'HELLOWORLDKLA_01.00.0000.iar',
'HELLO_KLA_01.00.0000.iar',
'KLA_01.22.7895.iar',
'KLA_HELLO_WORLD_2_01.00.0000.iar',
'KLA_02_WORLD_01.00.0000.iar'
]
[]
Above are the actual 2 arrays I am working with. The first array is just a simply array of filenames. The bottom array has been run through both sync and you async/await solution. For some reason even with the RegExp added it still picks up 2 files which are not listed in the filename array. I added the file paths to show none of the files are in the root directory and I spread out the files into sub directories to ensure the recursive search is working. I will keep messing with it to see if I can figure out why the RegExp solution is bringing these files into the array when they shouldn't be....
I'm afraid I don't have enough reputation to comment so am posting an answer!
Your code seems to work and if I understand rightly that you want to find all files from a list against a directory and sub directories giving you the paths to these files. Is that correct?
When I ran your code it does indeed pick up the four files in newFileArr and excludes the 1.txt, I've created a codesandbox demo to show you with dummy files.
I've also taken the liberty to create a codesandbox that demonstrates how to do this in a single function using RegExp and map to create dynamic regex expressions if that is useful.
I am having an issue checking for the URL in the pages on my site.
This is what I have.
Checking for the exact string works well:
var url = location.pathname;
if ("url:contains('texas-ignition-interlock')") {
$("body").addClass("texas-ppc-page");
}
But when I have page url with similar words, both classes were added to both pages.
var url = location.pathname;
if ("url:contains('texas-ignition-interlock-device')") {
$("body").addClass("texas-ppc-device-page");
}
I also tried indexOf, and is didn't work do to the pages with similar names.
This is what I tried, and this works for the first example. Second example will have the first class added too.
if (window.location.href.indexOf("texas-ignition-interlock") > -1) {
$("body").addClass("texas-ppc-page");
}
if (window.location.href.indexOf("texas-ignition-interlock-devices") > -1) {
$("body").addClass("texas-ppc-device-page");
}
Now, I can still use the indexOf version. I would simply target the stuff on one page using the class .texas-ppc-page, and on the second page I would target using both classes of .texas-ppc-page.texas-ppc-device-page.
Is there a better way of doing this with JS or jQuery?
You can use split("/") to split location.pathname into string arrays.
location.pathname will be similar to /questions/41968769/checking-for-exact-url so by splitting this string with "/" will result into
["", "questions", "41968769", "checking-for-exact-url"]
now you can perform indexOf("") and it will return non -1 value if string matched exactly, like in this case if i do indexOf("url") function will return -1, and if i do indexOf("checking-for-exact-url") it will return 3.
If you prefer to examine the strings similarly to how you were, you can leverage a regex, via .test as seen below with the placeholders ^ and $, for start and end, respectively. Otherwise, indexOf will match even a portion of the string. Check out the following...
var url = 'texas-ignition-interlock-devices';
console.log(/^texas-ignition-interlock$/.test(url)); // false
console.log(/^texas-ignition-interlock-devices$/.test(url)); // true
I want to trigger a digital marketing tag on every page which falls under a particular URL path, say example.com/sachin under the sachin directory.
I've tried if (location.href === 'example.com/sachin.*/') but somehow the condition doesn't seem to work.
What will be the correct if condition for location.href if I want to cover all different resources with in the URL path say under sachin directory?
I presume you want to check if the URL contains example.com/sachin. It's highly rarely that any URL ever would contain 4 forward-slashes but what you would do is utilize indexOf.
if(location.href.indexOf("example.com/sachin/") != -1){
//Do something
}
This basically says, if "example.com/sachin/" is found somewhere in the given string(in location.href in this case) on an indexposition that is not -1(which means that it doesn't exist), then execute.
You need to use Regular Expressions to match needed resources.
Something like that:
if(location.href.match(/^http:\/\/example.com\/sachin\//)){
//your staff here
}
Another approach to check for a specific directory in a url.
function urlContains(url, value) {
return ~url.indexOf(value);
}
if (urlContains(location.href, "/sachin/")) {
// found
} else {
// not found
}
The indexOf method checks a string for the value that is passed and returns -1 if a result was not found.
Instead of checking for == -1 or != -1 you can use the Bitwise NOT operator ~ to convert -1 to 0, which is a falsy value, non-zero values are treated are truthy values in javascript.
We're trying to compare the same file name, one is set by = operator, the other is returned by getting the file from Nodejs server after uploaded, as the following code block:
var name = "tên_đẹp.WAV";
// uploaded_file is the file (tên_đẹp) returned by calling an ajax function
// to get the uploaded file in uploaded_folder of a Nodejs server
ajaxUploadFile(name).done( function(e, uploaded_file) {
if(name == uploaded_file.name) {
return uploaded_file; // This line is never reached
else {
console.log(escape(name)); // t%EAn_%u0111%u1EB9p.WAV
console.log(escape(uploaded_file.name)); // te%u0302n_%u0111e%u0323p.WAV
}
}
As you can see the result of the 2 escape commands are different.
I don't know why they use different unicode format and how can I make them use the same Unicode charset or any solution would be much appreciated?
Thanks.
The issue is that "e\u0302" and "\u00EA" are both visually identical. One is the specific character U+00EA (LATIN SMALL LETTER E WITH CIRCUMFLEX), and the other is e with the combining character U+0302 (COMBINING CIRCUMFLEX ACCENT). You must normalize each string to a standard form first to compare them.
require('unorm');
var name = "tên_đẹp.WAV";
// uploaded_file is the file (tên_đẹp) returned by calling an ajax function
// to get the uploaded file in uploaded_folder of a Nodejs server
ajaxUploadFile(name).done( function(e, uploaded_file) {
if(name.normalize() == uploaded_file.name.normalize()) {
return uploaded_file; // This line is never reached
else {
console.log(escape(name)); // t%EAn_%u0111%u1EB9p.WAV
console.log(escape(uploaded_file.name)); // te%u0302n_%u0111e%u0323p.WAV
}
}
Note that I've loaded the unorm module, which polyfills in the .normalize() method being called on the strings. This method is part of ECMA6, and in future versions of Node you will not need to load unorm at all.
It's impossible to say what introduced the differences there, it could have been your text editor or your browser.
%EA == ê
e%u0302 == e + ^
These are two unicode sequences that look the same, but typed differently. If you're need to compare them, you'll have to do unicode normalization first.
The unicode characters in uploaded_file.name are accents. %u0302 is a diacritical mark COMBINING CIRCUMFLEX ACCENT, %u0323 is a diactritical mark COMBINING DOT BELOW.
On the other hand, %EA (ê) and %u1EB9 (ẹ) are the equivalent characters with accents integrated.
This is something handled by Unicode equivalence (see Wikipedia). The sequence of e%u0302 is said to be canonicaly equivalent to %EA, and similarly for the other pair.
To handle the comparison properly in node.js, you have to normalize the strings into a canonical form (NFC or NFD). This can be achieved with unorm:
var unorm = require('unorm');
var s1 = 'êẹ';
var s2 = 'e\u0302e\u0323';
console.log(s1 == s2); // false
console.log(unorm.nfc(s1) == unorm.nfc(s2)); // true
console.log(unorm.nfd(s1) == unorm.nfd(s2)); // true
The choice between NFC (composed) and NFD (decomposed) should not matter in this case.
Important: Note that canonicalization can sometimes introduce nonobvious exploitable vulnerabilities, especially with filenames, as the OS would likely still see them as different. E.g. see this story of spotify: Creative usernames and Spotify account hijacking.
What I want to accomplish is simple. I want a button's text to change depending on what page your on.
I start this by using the following:
var loc_array = document.location.href.split('/');
Now that I have the url and split it in an array I can grab certain directories depending on the position, like so:
if (loc_array[loc_array.length-1] == 'stations'){
var newT = document.createTextNode("Stations & Maps");
}
Now this works if the directory is /test/stations/, however if someone types /test/stations/index.html then it doesn't work. How can you test against this without throwing in another if statement or using a similar conditional.
Actually both your examples work the same. /stations/ and /stations/index.html both get split into two strings; /stations/ has an empty string at the end. So length-2 would have worked. Where it wouldn't work would be /stations, which is up a level. But that wouldn't normally be an issue because if stations is a static directory, the web server will redirect the browser to /stations/ with the slash.
That won't happen if you're doing the routing yourself. If you're doing routing, it's not a good idea to index from the end of the list of path parts, are there might be any old rubbish there being passed as path-parameters, eg. /stations/region1/stationname2. In this case you should be indexing from the start instead.
If the application can be mounted on a path other than a root you will need to tell JavaScript the path of that root, so it can work out how many slashes to skip. You'll probably also need to tell it for other purposes, for example if it creates any images on the fly it'll need to know the root to work out the directory to get images from.
var BASE= '/path-to/mysite';
var BASELEVEL= BASE.split('/').length;
...
var pagename= location.pathname.split('/')[BASELEVEL];
// '/path-to/mysite/stations/something' -> 'stations'
I'm using location.pathname to extract only the path part of the URL, rather than trying to pick apart href with string or regex methods, which would fail for query strings and fragment identifiers with / in them.
(See also protocol, host, port, search, hash for the other parts of the URL.)
I don't think string splitting is the best approach here. I would do it using RegEx.
var reStations = /\/stations(\/)?/i;
if (reStations.test(document.location.href))
//Do whatever
Not sure exactly what you're looking for, see if this fits:
var loc_array = document.location.href.split('/');
// this will loop through all parts
foreach (var i in loc_array) {
switch (loc_array[i]) {
case "stations":
// do something
break;
// other cases
}
}
// or if you want to check each specific element
switch (loc_array[0]) {
case "stations": // assuming /stations/[something/]
if (typeof loc_array[1] != 'undefined' && loc_array[1] == "something") {
// do things
}
break;
}
if( document.location.href.split( "station" ).length > 1 ){
//...
}
I think I see where you are going with this... As someone stated above using a RegExp (regular expression) could be helpful... but ONLY if you had more than a single type of page to filter out (html/js/php/...), but for what it looks like you want to do. Try something like this:
var loc_array = document.location.href.split('/');
var i = loc_array.length-1;
var button_label = "default";
while(i>1)
{
//checks to see if the current element at index [i] is html
if(loc_array[i].indexOf(".html")>-1)
{
if(i>0)
{
var button_label = loc_array[i-1];
break;
}
}
i--;
}
alert(button_label);
What it does is:
capture the current URL(URI)
split it into an array
starting from the END of the array and working BACKWARDS, look for the first element that contains the ".html" file identifier.
We now know that the element BEFORE our current element contains the label we want to add to our buttons...
You can then take the value and assign it wherever you need it.
If you run out of elements, it has a default value you can use.
Not sure if this helps.....
I have tested the above code and it worked.
if (loc_array[4]=='stations')
if the url was http://www.example.com/test/stations/index.html, the values in the array would be:
[0] = "http:"
[1] = ""
[2] = "www.example.com"
[3] = "test"
[4] = "stations"
[5] = "index.html"
For simplicity's sake, supposing that there is an array of keywords (such as "station") that identify the pages, use a map and try to match its keys with the href string using indexOf,
var href = document.location.href ;
var identifiers = {
"station": "Stations & Maps" , //!! map keys to result strings
/* ... */
} ;
identifier_loop: //!! label to identify the current loop
for(var n in identifiers) { //!! iterate map keys
if( href.indexOf(n) !== -1 ) { //!! true if the key n in identifiers is in the href string
var newT = document.createTextNode( identifiers[n] ) ; //!! create new text node with the mapped result string
break identifier_loop ; //!! end iteration to stop spending ressources on the loop
}
}
Your example will show an empty string, cause the last item is empty; so you can simply make:
if (loc_array[loc_array.length-2] == 'stations')
{
var newT = document.createTextNode("Stations & Maps");
}