I can replace a normal string using:
var strNew = strContent.replace("subject", "replacement");
The above works find, however:
var strNew = strContent.replace("{subject}", "replacement");
Doesn’t work, is there something I need to do?
I’ve tried:
var strNew = strContent.replace("/{/gsubject/}/g", "replacement");
Didn’t work either…
[Edit] Something is very wrong, I’ve added more debug, BTW, this is run by Node.js v21.7.1 on Windows 10.I read a HTML page from MariaDB, this is read into a string:
<!DOCTYPE html><html><head><meta http-equiv="X-UA-Compatible" content="IE=Edge" /><meta http-equiv="content-type" content="text/html; charset=utf-8"><meta name="author" content="Simon Platten"><title>Quintex, no company</title><link rel="stylesheet" href="/scripts/jquery/jquery-ui.min.css" class="ui-theme"/><link rel="stylesheet" href="/scripts/jquery/jqwidgets/styles/jqx.base.css"/><link rel="stylesheet" href="/scripts/jquery/jqwidgets/styles/jqx.darkblue.css"/><link rel="stylesheet" href="/styles/common.css"/>
<style type="text/css">body { background: #ffffff url("images/quintex.png") no-repeat 4px 4px; font-family: 'Open Sans', sans-serif; overflow-y: scroll; font-size: 9pt; } h1 { padding-bottom: 5px; font-size: 14pt; color: #124a9d; } a { text-decoration: none; color: #124a9d; } a:hover { text-decoration: underline; color: #124a9d; } a.mnubtn { text-decoration: none; text-align: center; color: #ffffff; } .ui-dialog-osx { -moz-border-radius: 0 0 8px 8px; -webkit-border-radius: 0 0 8px 8px; border-radius: 0 0 8px 8px; border-width: 0 8px 8px 8px; } .ui-widget-header { background: #0000ff url("/images/menubar.jpg") repeat-x scroll 50% 50%; } #svrinfo { background-color: #0000ff; text-align:center; font-weight: bold; position:abolute; font-size: 14pt; color: #ffff00; z-index: 9999; display: none; } #loading { transform: translate(-50%, -50%); position: fixed; z-index: 99999; left:50%; top:50%; } footer { text-align: center; position:absolute; font-size: 9pt; width: 100%; bottom: 0px; }
</style><script type="text/javascript" src="/scripts/modernizr.js"></script><script type="text/javascript" src="/scripts/jquery/jquery-2.2.1.min.js"></script><script type="text/javascript" src="/scripts/jquery/jquery-ui.min.js"></script><script type="text/javascript" src="/scripts/jquery/jqwidgets/jqxcore.js"></script><script type="text/javascript" src="/scripts/jquery/jqwidgets/jqxbuttons.js"></script><script type="text/javascript" src="/scripts/jquery/jqwidgets/jqxscrollbar.js"></script><script type="text/javascript" src="/scripts/jquery/jqwidgets/jqxlistbox.js"></script><script type="text/javascript" src="/scripts/jquery/jqwidgets/jqxcombobox.js"></script><script type="text/javascript" src="/scripts/jquery/jqwidgets/jqxpasswordinput.js"></script><script type="text/javascript" src="/scripts/jquery/jqwidgets/jqxbuttons.js"></script><script type="text/javascript" src="/socket.io/socket.io.js"></script><script type="text/javascript" src="/scripts/consts.js"></script>
<script type="text/javascript" language="javascript">
<!--
var strSocketServer = "ws://{HOST}"
,blnSocketConnected, socket;
$(document).ready(function() {
var svrinfo = $("#svrinfo");
//Show the loading image whilst processing
$("#loading").show();
if ( !svrinfo ) {
alert("Cannot find tag 'svrinfo' in document!");
}
//Install timer to maintain socket connection
setInterval(function() {
try{
if ( !socket ) {
socket = io.connect(strSocketServer);
if ( socket ) {
socket.on(SCKMSG_CONNECT, function() {
//Connected!
});
socket.on(SCKMSG_DISCONNECT, function() {
//Disconnected!
});
socket.on(SCKMSG_LIST_CMPY, function(aryCompanies) {
//People list
var objCompanies = $('#cmpy');
if ( aryCompanies && aryCompanies.length ) {
for( var c in aryCompanies ) {
var objCompany = aryCompanies[c];
//What controls are available in the DOM?
if ( objCompanies && objCompanies.length ) {
$(objCompanies).append("<option value='" + objCompany['ckey']
+ "'>" + objCompany['n'] + "</option>");
}
}
//Hide the processing overlay
$("#loading").hide();
}
showContent();
});
}
}
if ( blnSocketConnected != undefined
&& (!socket || socket.disconnected) ) {
delete blnSocketConnected;
}
if ( !socket ) {
$(svrinfo).text("Cannot create socket!");
} else if ( !socket.connected ) {
if ( socket.disconnected ) {
$(svrinfo).text("Server has gone away!");
} else {
$(svrinfo).text("Connecting to server: " + strSocketServer);
}
} else {
$(svrinfo).text("Connected to server: " + strSocketServer);
}
if ( socket && blnSocketConnected != socket.connected ) {
$(svrinfo).show();
blnSocketConnected = socket.connected;
if ( blnSocketConnected ) {
//Hide the server status message
$(svrinfo).hide();
//Request people list
socket.emit(SCKMSG_LIST_REQCMPY);
}
}
} catch(ex) {
}
}, 500);
});
// -->
</script>
</head><body><div id="svrinfo"></div>{CONTENT}<footer>{FOOTER}</footer><img id="loading" src="/images/loading.gif" width="250" height="70"/></body></html>
My macro definitions:
//PM = Page Macro
,PM_COMPANY = "{COMPANY}"
,PM_CONTENT = "{CONTENT}"
,PM_FOOTER = "{FOOTER}"
,PM_HEADER = "{HEADER}"
,PM_HOST = "{HOST}"
,PM_LAST_FAILED_LOGIN = "{dtLFLOGIN}"
,PM_LOGO_IMG = "{LOGO_IMG}"
,PM_LOGO_IMG_ALT = "{LOGO_IMG_ALT}"
,PM_LOGO_IMG_HEIGHT = "{LOGO_IMG_HEIGHT}"
,PM_LOGO_IMG_WIDTH = "{LOGO_IMG_WIDTH}"
,PM_PREFS = "{PREFS}"
,PM_UID = "{UID}"
An example of the replace logic:
strPage = strPage.replace(consts.PM_HOST, strHost);
However it just isn’t working…I’ve tried putting in escape codes around { and }, no difference.
I’ve just added more debug reporting to the console, after running it shows:
L183 before replace strPage.indexOf({HOST}): 2585
L185 after replace strPage.indexOf({HOST}): -1
L195 before replace strPage.indexOf({COMPANY}): -1
L197 after replace strPage.indexOf({COMPANY}): -1
L218 before replace strPage.indexOf({PREFS}): -1
L220 after replace strPage.indexOf({PREFS}): -1
L243 before replace strPage.indexOf({CONTENT}): 4833
L245 after replace strPage.indexOf({CONTENT}): 9709
L299 before replace strPage.indexOf({HEADER}): -1
L301 after replace strPage.indexOf({HEADER}): -1
L306 before replace strPage.indexOf({FOOTER}): 9726
L308 after replace strPage.indexOf({FOOTER}): 9943
Each line above is around a replace statement, some like the COMPANY, PREFS and HEADER will return -1 because these aren’t present in the content, why is CONTENT and FOOTER found after the replace?
[Edit2] New function, thank you to Andy:function replaceMacro(strContent, cstrMacro, strReplacement) {
if ( !(typeof strContent == "string"
&& typeof strContent.length == "number"
&& strContent.length > 0
&& typeof cstrMacro == "string"
&& typeof cstrMacro.length == "number"
&& cstrMacro.length > 0
&& typeof strReplacement == "string"
&& typeof strReplacement.length == "number") ) {
return strContent;
}
let strUpdated = strContent;
const cRegEx = new RegExp(cstrMacro, 'g');
console.log(consts.RED + "L177 replaceMacro, searching for " + cstrMacro + ": " + String(strContent.indexOf(cstrMacro)) + consts.RESET); //HACK
strUpdated = strUpdated.replaceAll(cRegEx, strReplacement);
console.log(consts.RED + "L179 replaceMacro, searching for " + cstrMacro + ": " + String(strUpdated.indexOf(cstrMacro)) + consts.RESET); //HACK
return strUpdated;
}
Much better but still finds {CONTENT} after the replace. Example of the call that still fails:
strPage = replaceMacro(strPage, consts.PM_CONTENT, strContent);
Where PM_CONTENT contains "{CONTENT}" and strContent contains the HTML to replace the macro with.
4
Answers
Could you provide a minimal example where we can see it go wrong? IMO this just works.
You can use positive lookahead and positive lookbehind
Also
is not a regex
This is a regex:
Regex starts with
/
and not"
It’s possible that the part you’re missing is how to use an actual word from the macro in the regular express. You can do that by using the
new RegExp
constructor.For example:
new RegExp(`{${obj.subject}}`, 'g')
which I’ve elaborated on below. Note: I’ve used an array of objects to defined the subjects/replacements instead of a macro.Additional documentation
Template/string literals
RegExp contructor
replaceAll
It seems that it does work, according to your log output. In some cases the string is no longer found (-1) after replacing, because its only occurrence was replaced. In other cases it is found at a new location later in the string, because it exists multiple times and the first occurrence just got replaced.
Maybe the issue is that you expect it to replace all occurrences? In this case you need to use
replaceAll
instead ofreplace
if you use a string as needle argument:Or, use a regex with the
g
(global) modifier: