Regular Expressions 101

Save & Share

  • Regex Version: ver. 1
  • Update Regex
    ctrl+⇧+s
  • Save new Regex
    ctrl+s
  • Add to Community Library

Flavor

  • PCRE2 (PHP >=7.3)
  • PCRE (PHP <7.3)
  • ECMAScript (JavaScript)
  • Python
  • Golang
  • Java 8
  • .NET 7.0 (C#)
  • Rust
  • Regex Flavor Guide

Function

  • Match
  • Substitution
  • List
  • Unit Tests

Tools

Sponsors
There are currently no sponsors. Become a sponsor today!
An explanation of your regex will be automatically generated as you type.
Detailed match information will be displayed here automatically.
  • All Tokens
  • Common Tokens
  • General Tokens
  • Anchors
  • Meta Sequences
  • Quantifiers
  • Group Constructs
  • Character Classes
  • Flags/Modifiers
  • Substitution
  • A single character of: a, b or c
    [abc]
  • A character except: a, b or c
    [^abc]
  • A character in the range: a-z
    [a-z]
  • A character not in the range: a-z
    [^a-z]
  • A character in the range: a-z or A-Z
    [a-zA-Z]
  • Any single character
    .
  • Alternate - match either a or b
    a|b
  • Any whitespace character
    \s
  • Any non-whitespace character
    \S
  • Any digit
    \d
  • Any non-digit
    \D
  • Any word character
    \w
  • Any non-word character
    \W
  • Non-capturing group
    (?:...)
  • Capturing group
    (...)
  • Zero or one of a
    a?
  • Zero or more of a
    a*
  • One or more of a
    a+
  • Exactly 3 of a
    a{3}
  • 3 or more of a
    a{3,}
  • Between 3 and 6 of a
    a{3,6}
  • Start of string
    ^
  • End of string
    $
  • A word boundary
    \b
  • Non-word boundary
    \B

Regular Expression
No Match

r"
"
g

Test String

Substitution

Processing...

Code Generator

Generated Code

# coding=utf8 # the above tag defines encoding for this document and is for Python 2.x compatibility import re regex = r"(?m)((?:(?:^[ \t]*)?(?:/\*[^*]*\*+(?:[^/*][^*]*\*+)*/(?:[ \t]*\r?\n(?=[ \t]*(?:\r?\n|/\*|//)))?|//(?:[^\\]|\\(?:\r?\n)?)*?(?:\r?\n(?=[ \t]*(?:\r?\n|/\*|//))|(?=\r?\n))))+)|((?:\"[^\"\\]*(?:\\[\S\s][^\"\\]*)*\"|'[^'\\]*(?:\\[\S\s][^'\\]*)*'|(?:\r?\n(?:(?=(?:^[ \t]*)?(?:/\*|//))|[^/\"'\\\r\n]*))+|[^/\"'\\\r\n]+)+|[\S\s][^/\"'\\\r\n]*)" test_str = ("/* Some of these types off comments\n" "more here and here ...\n" "*/\n\n" "////////////////////////////////////////////////////////////////////////////////\n" "//\n" "// THIS CODE IS NOT APPROVED FOR USE IN/ON ANY OTHER UI ELEMENT OR PRODUCT COMPONENT.\n" "// Copyright (c) 2009 Microsoft Corporation. All rights reserved.\n" "//\n" "////////////////////////////////////////////////////////////////////////////////\n" "var g_oService;\n" "var g_oCurr = new Array(4);\n" "var g_oTimer = null;\n" "var g_StartValue = 1;\n" "var g_sRowCount = 1;\n" "var g_sRowHeight = 54;\n" "var g_sBodyHeight;\n" "var g_sMenuHeight;\n" "var g_sFullName = true;\n" "var g_dataFromService;\n" "var g_isStaleData = false;\n" "var g_ageStampText = \"\";\n" "var spinner;\n" " \n" "////////////////////////////////////////////////////////////////////////////////\n" "//\n" "// Load gadget's main function\n" "//\n" "////////////////////////////////////////////////////////////////////////////////\n" "function loadMain()\n" "{\n" " // Set initial values needed for dynamic re-sizing of menu and rows\n" " g_sBodyHeight = parseInt(document.body.currentStyle.height);\n" " \n\n" " // Check if gadget is new or reloaded with sidebar\n" " if (readSetting('rowCount'))\n" " {\n" " g_sRowCount = readSetting('rowCount');\n" " }\n" " else\n" " {\n" " saveSetting('rowCount', g_sRowCount);\n" " }\n" " spinner = new getSpinner('messageSpinner');\n" " localizeUI();\n\n" " SetUIState('loading');\n" " \n" " g_oService = new CurrencyService()\n" " g_oService.OnDataReady = DataReady;\n" " \n" " // If we are actually running in the gadget platform\n" " // wire up all the events.\n" " if (gGadgetMode)\n" " { \n" " System.Gadget.onDock = DockGadget;\n" " System.Gadget.onUndock = UndockGadget;\n" " \n" " if (System.Gadget.docked)\n" " {\n" " DockGadget();\n" " }\n" " else\n" " {\n" " UndockGadget();\n" " }\n" " }\n" " else\n" " {\n" " UndockGadget();\n" " }\n" " \n" " // Attaching events to the toolbar buttons\n" " addButton.attachEvent(\"onmouseover\", function(){addButton.style.backgroundImage = 'url(../images/add_over.png)';});\n" " addButton.attachEvent(\"onclick\", function(){addButton.style.backgroundImage = 'url(../images/add_down.png)'; addRow();});\n" " addButton.attachEvent(\"onmouseout\", function(){addButton.style.backgroundImage = 'url(../images/add_up.png)';});\n" " addButton.attachEvent(\"onfocus\", function(){addButton.style.backgroundImage = 'url(../images/add_down.png)';});\n" " addButton.attachEvent(\"onblur\", function(){addButton.style.backgroundImage = 'url(../images/add_up.png)';});\n" " addButton.title = L_localizedStrings_Text['Add']\n" " \n" " g_StartValue = g_StartValue.toLocaleString(); \n" " g_oCurr[0].oTextBox.value = g_StartValue; \n" " g_oService.GetCurrencies(); \n" " \n" " if (System.Gadget.docked)\n" " {\n" " document.getElementById('curr0input').style.display = 'block';\n" " document.getElementById('curr1input').style.display = 'block';\n" " }\n" " \n" " \n" "}\n" "////////////////////////////////////////////////////////////////////////////////\n" "//\n" "// Localize all data\n" "//\n" "////////////////////////////////////////////////////////////////////////////////\n" "function localizeUI()\n" "{\n" " for (var i = 0; i < g_oCurr.length; i++)\n" " {\n" " g_oCurr[i] = new CurrencyBox('curr' + i, getLocalizedString('GettingExchangeRate'), '0');\n" " // reverse reference in array\n" " g_oCurr[i].oTextBox.setAttribute('arrayIdx', i);\n" " g_oCurr[i].oTextBox.onkeyup = OnAmountChange;\n" " }\n" " \n" " var oDataLink = document.getElementById('dataLink');\n" " oDataLink.innerHTML = getLocalizedString('DataProviders');\n" " oDataLink.href = getLocalizedString('MSNMoneyURL');\n" "}\n" "////////////////////////////////////////////////////////////////////////////////\n" "//\n" "// Creates a currency row for each id in g_oCurr array\n" "//\n" "////////////////////////////////////////////////////////////////////////////////\n" "function CurrencyBox(oControl, sCaption, sValue)\n" "{\n" " // Self reference\n" " var me = this;\n" " \n" " // Private data members\n" " var m_oCaption = '';\n" " var m_sCaption = sCaption;\n" " var m_oControl = oControl;\n" " var oDeleteButton;\n" " var oCurrOnline;\n" " var oValueDiv;\n" " var oTextBoxBack;\n" " var sCurrCount = oControl.replace('curr', '');\n" " var tableCurr;\n" " var oTableCaption;\n" " var oTD = new Array();\n" " var oTDCaption = new Array();\n" " var oCaptionA;\n" " var oCurrencyImage;\n" " \n" " // Public Properties\n" " this.oTextBox = null;\n" " this.oTag = null;\n" " \n" " // Get currency div\n" " m_oControl = document.getElementById(oControl);\n" " \n" " // Private methods\n" " function Initialize()\n" " {\n" " // Create table \n" " tableCurr = document.createElement('<table cellpadding=\"0\" cellspacing=\"0\" border=\"0\"></table>');\n" " var tbCurr = document.createElement('tbody');\n" " var trCurr = document.createElement('tr');\n" " tableCurr.appendChild(tbCurr);\n" " tbCurr.appendChild(trCurr);\n" " for (j=0;j<3;j++)\n" " {\n" " oTD[j] = document.createElement('td'); \n" " oTD[j].setAttribute(\"id\", m_oControl.id + \"TD\" + j);\n" " trCurr.appendChild(oTD[j]); \n" " } \n" " \n" " // Create table for Caption and left-right borders \n" " oTableCaption = document.createElement('<table cellpadding=\"0\" cellspacing=\"0\" border=\"0\"></table>');\n" " var oTBCaption = document.createElement('tbody');\n" " var oTRCaption = document.createElement('tr');\n" " oTableCaption.appendChild(oTBCaption);\n" " oTBCaption.appendChild(oTRCaption);\n" " for (j=0;j<3;j++)\n" " {\n" " oTDCaption[j] = document.createElement('td'); \n" " oTDCaption[j].setAttribute(\"id\", m_oControl.id + \"TDCaption\" + j);\n" " oTRCaption.appendChild(oTDCaption[j]); \n" " } \n" " \n" " // Create container for text/textbox\n" " oValueDiv = document.createElement('div');\n" " oValueDiv.id = m_oControl.id + 'value';\n" " \n" " // Create currency text\n" " var oLabel = document.createElement('label');\n" " oLabel.id = m_oControl.id + 'label';\n" " m_oCaption = document.createElement('div');\n" " m_oCaption.id = m_oControl.id + 'caption';\n" " \n" " if(document.dir == 'rtl')\n" " {\n" " m_oCaption.onmouseover = function() {oTDCaption[0].style.backgroundImage = 'url(../images/combo-hover-right.png)';\n" " oTDCaption[1].style.backgroundImage = 'url(../images/combo-hover-middle.png)';\n" " oTDCaption[2].style.backgroundImage = 'url(../images/combo-hover-left.png)';};\n" " }\n" " else\n" " {\n" " m_oCaption.onmouseover = function() {oTDCaption[0].style.backgroundImage = 'url(../images/combo-hover-left.png)';\n" " oTDCaption[1].style.backgroundImage = 'url(../images/combo-hover-middle.png)';\n" " oTDCaption[2].style.backgroundImage = 'url(../images/combo-hover-right.png)';};\n" " }\n" " \n" " m_oCaption.onmouseout = function() {oTDCaption[0].style.backgroundImage = '';\n" " oTDCaption[1].style.backgroundImage = '';\n" " oTDCaption[2].style.backgroundImage = '';};\n" " \n" " oLabel.appendChild(m_oCaption);\n" " \n" " //Create Caption A HREF and triangle image\n" " oCaptionA = document.createElement('a');\n" " oCaptionA.id = 'captionA';\n" " oCaptionA.href = \"javascript:void;\";\n" " if ( g_isStaleData )\n" " {\n" " oCaptionA.title = getLocalizedString('ServiceNotAvailable');\n" " }\n" " else\n" " {\n" " oCaptionA.title = m_sCaption;\n" " }\n" " oCaptionA.innerHTML = m_sCaption; \n" " oCurrencyImage = document.createElement('img');\n" " oCurrencyImage.id = \"currencyImage\";\n" " oCurrencyImage.src = 'images/triangle.png';\n" " oCurrencyImage.border = '0';\n" " \n" " oCaptionA.onclick = function() {showCurrencyList(oControl);};\n" " oCaptionA.appendChild(oCurrencyImage);\n" " m_oCaption.appendChild(oCaptionA);\n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " // Create button for online currency\n" " oCurrOnline = document.createElement('div');\n" " oCurrOnline.id = m_oControl.id + 'OnlineButton';\n" " oCurrOnlineA = document.createElement('a');\n" " oCurrOnlineA.id = m_oControl.id + 'OnlineButtonA';\n" " oCurrOnlineA.target = '_blank';\n\n" " if ( g_isStaleData )\n" " {\n" " oCurrOnlineA.title = getLocalizedString('ServiceNotAvailable');\n" " }\n" " else\n" " {\n" " oCurrOnlineA.title = L_localizedStrings_Text['Graph'];\n" " }\n\n" " oCurrOnlineAImg = document.createElement('img');\n" " oCurrOnlineAImg.border = '0';\n" " oCurrOnlineAImg.src = '../images/graph_up.png';\n" " oCurrOnlineAImg.onmousedown = function() {this.src = '../images/graph_down.png';};\n" " oCurrOnlineAImg.onmouseover = function() {this.src = '../images/graph_over.png';};\n" " oCurrOnlineAImg.onmouseout = function() {this.src = '../images/graph_up.png';}; \n" " \n" " oCurrOnlineA.appendChild(oCurrOnlineAImg);\n" " oCurrOnline.appendChild(oCurrOnlineA);\n" " \n" " // Create delete button\n" " oDeleteButtonA = document.createElement('a');\n" " oDeleteButtonA.setAttribute(\"href\",\"javascript:void;\");\n" " oDeleteButtonA.setAttribute(\"title\",L_localizedStrings_Text['Remove']);\n" " oDeleteButtonA.style.backgroundImage = 'url(../images/delete_up.png)';\n" " oDeleteButton = document.createElement('div');\n" " oDeleteButton.id = m_oControl.id + 'DeleteButton'; \n" " oDeleteButton.style.backgroundImage = 'url(../images/delete_up.png)';\n" " oDeleteButtonA.onclick = function() {oDeleteButton.style.backgroundImage = 'url(../images/delete_down.png)'; deleteRow(oControl);};\n" " oDeleteButton.onmouseover = function() {this.style.backgroundImage = 'url(../images/delete_over.png)';};\n" " oDeleteButton.onmouseout = function() {this.style.backgroundImage = 'url(../images/delete_up.png)';}; \n" " oDeleteButtonA.onfocus = function() {if(m_oControl.id.replace('curr', '') !='0' && g_sRowCount > 1){oDeleteButton.style.backgroundImage = 'url(../images/delete_over.png)';oDeleteButton.style.display = 'block';} };\n" " oDeleteButtonA.onblur = function() {oDeleteButton.style.backgroundImage = 'url(../images/delete_up.png)'; oDeleteButton.style.display = 'none'; };\n" " oDeleteButtonA.appendChild(oDeleteButton);\n" " \n" " // Create the textbox\n" " me.oTextBox = document.createElement('input');\n" " me.oTextBox.id = oLabel.htmlFor = m_oControl.id + 'input';\n" " me.oTextBox.type = 'text';\n" " me.oTextBox.maxLength = 20;\n" " me.oTextBox.value = sValue;\n" " \n" " // Create the textbox background\n" " oTextBoxBack = document.createElement('div');\n" " oTextBoxBack.id = m_oControl.id + 'InputBack'; \n" " \n" " oValueDiv.appendChild(tableCurr);\n" " oValueDiv.appendChild(me.oTextBox);\n" " oValueDiv.appendChild(oTextBoxBack);\n" " \n" " // Add everything in and make it accessible\n" " m_oControl.appendChild(oValueDiv);\n" " \n" " tableCurr.style.height = '21px';\n" " oTableCaption.style.height = '21px';\n" " tableCurr.style.position = 'absolute';\n" " \n" " oTD[0].style.width = '16px';\n" " oTDCaption[0].style.width = '3px';\n" " oTDCaption[2].style.width = '3px';\n" " oTD[2].style.width = '16px'; \n" " oTD[0].appendChild(oCurrOnline);\n" " oTD[1].appendChild(oTableCaption);\n" " oTDCaption[1].appendChild(oLabel);\n" " oTD[2].appendChild(oDeleteButtonA); \n" " \n" " me.setCaption(m_sCaption);\n" " }\n" " \n" " this.setCaption = function(sCaption)\n" " {\n" " if ( g_isStaleData )\n" " {\n" " oCaptionA.title = getLocalizedString('ServiceNotAvailable');\n" " }\n" " else\n" " {\n" " oCaptionA.title = sCaption;\n" " }\n\n" " oCaptionA.innerHTML = sCaption + oCurrencyImage.outerHTML;\n" " \n" " \n" " }\n\n" " // Set styles depending on docked or undocked\n" " this.changeMode = function(sMode)\n" " {\n" " if (sMode == 'docked')\n" " {\n" " oTD[0].style.display = 'none';\n" " oTD[2].style.display = 'none';\n" " tableCurr.style.width = '43px'; \n" " tableCurr.style.left = '9px';\n" " tableCurr.style.right = '9px';\n" " tableCurr.style.top = '9px'; \n" " \n" " var sCurr = readSetting(oControl) || L_localizedStrings_Text['default'+sCurrCount];\n" " this.setCaption(sCurr);\n" " curr1.style.top = '27px';\n" " tableCurr.className = 'tableFont';\n" " oTableCaption.className = 'tableCaption';\n" " m_oControl.className = 'dockedCurrencyContainer';\n" " m_oCaption.className = 'dockedCurrencyTitle';\n" " if(document.dir == 'rtl')\n" " {\n" " me.oTextBox.className = 'dockedCurrencyValueRtl';\n" " oTextBoxBack.className = 'dockedCurrencyValueBackRtl';\n" " }\n" " else\n" " {\n" " me.oTextBox.className = 'dockedCurrencyValue';\n" " oTextBoxBack.className = 'dockedCurrencyValueBack';\n" " }\n" " oValueDiv.className = 'dockedCurrencyDiv';\n" " oCurrOnline.className = 'dockedCurrencyOnlineButton';\n" " oDeleteButton.className = 'dockedCurrencyDeleteButton';\n" " currencyList.className = 'dockedCurrencyList';\n" " document.getElementById('currencySelect').className = 'dockedCurrencySelect';\n" " document.getElementById('currencySelect').size = 4;\n" " document.getElementById('bottomTable').style.display = 'none';\n" " m_oControl.onmouseover = '';\n" " m_oControl.onmouseout = '';\n" " oValueDiv.onmouseover = '';\n" " oValueDiv.onmouseout = '';\n" " g_sFullName = false;\n" " }\n" " // undocked\n" " else\n" " {\n" " oTD[0].style.display = 'block';\n" " oTD[2].style.display = 'block';\n" " tableCurr.style.width = '212px';\n" " tableCurr.style.left = '3px';\n" " tableCurr.style.right = '3px';\n" " tableCurr.style.top = '';\n" " \n" " var sCurr = readSetting(oControl) || L_localizedStrings_Text['default'+sCurrCount];\n" " this.setCaption(getLocalizedString(sCurr));\n" " curr1.style.top = g_sRowHeight;\n" " oDeleteButton.style.display = 'none';\n" " tableCurr.className = 'tableFont';\n" " oTableCaption.className = 'tableCaption';\n" " m_oControl.className = 'currencyContainer';\n" " m_oCaption.className = 'currencyTitle';\n" " me.oTextBox.className = 'currencyValue';\n" " me.oTextBox.style.display = '';\n" " oTextBoxBack.className = 'currencyValueBack';\n" " oValueDiv.className = 'currencyDiv';\n" " oCurrOnline.className = 'currencyOnlineButton';\n" " oDeleteButton.className = 'currencyDeleteButton';\n" " currencyList.className = 'undockedCurrencyList';\n" " document.getElementById('currencySelect').className = 'undockedCurrencySelect';\n" " document.getElementById('currencySelect').size = 4 + (g_sRowCount * 4);\n" " m_oControl.onmouseover = function() {showDelete(oControl)};\n" " m_oControl.onmouseout = function() {hideDelete(oControl)};\n" " oValueDiv.onmouseover = function() {this.style.background = 'url(../images/row_over.png) no-repeat';};\n" " oValueDiv.onmouseout = function() {this.style.background = '';};\n" " g_sFullName = true; \n" " }\n" " } \n\n" " // Constructor\n" " Initialize();\n" "}\n\n" "function setBackground(path)\n" "{\n" " // if you switch backgrounds on the fly, you must set the style size to zero\n" " // so it dynamically refreshes\n" " currencybackground.style.width = 0;\n" " currencybackground.style.height = 0;\n" " currencybackground.src = path;\n" "}\n\n" "////////////////////////////////////////////////////////////////////////////////\n" "//\n" "// Add currency row\n" "//\n" "////////////////////////////////////////////////////////////////////////////////\n" "function addRow()\n" "{\n" " if (g_sRowCount < 3)\n" " {\n" " g_sRowCount++;\n" " document.getElementById('curr'+g_sRowCount).style.display = 'block';\n" " document.body.style.height = parseInt(document.body.style.height) + g_sRowHeight; \n" " setBackground(\"url(images/base-undocked-\"+(g_sRowCount+1)+\".png)\");\n" " saveSetting('rowCount', g_sRowCount);\n" " document.getElementById('currencySelect').size += 4;\n" " if ( g_oService.IsAvailable )\n" " {\n" " loadSettings();\n" " }\n" " } \n" " \n" " // \"Deactivate\" add link if max rows reached\n" " if (g_sRowCount >= (g_oCurr.length - 1))\n" " {\n" " addButton.style.display = 'none';\n" " }\n" "}\n" "////////////////////////////////////////////////////////////////////////////////\n" "//\n" "// Remove currency row\n" "//\n" "////////////////////////////////////////////////////////////////////////////////\n" "function deleteRow(sControlId)\n" "{\n" " var sOptionCount = sControlId.replace('curr', '');\n" " // Must not delete if only 2 rows\n" " if(sOptionCount ==0 || g_sRowCount < 2)\n" " {\n" " return false;\n" " }\n" " \n" " sOptionCount *= 1;\n\n" " document.getElementById('curr'+g_sRowCount).style.display = 'none';\n" " document.getElementById(sControlId+'DeleteButton').style.display = 'none';\n" " document.body.style.height = parseInt(document.body.style.height) - g_sRowHeight;\n" " \n" " currencybackground.style.width = 0;\n" " currencybackground.style.height = 0;\n" " currencybackground.src = \"url(images/base-undocked-\"+(g_sRowCount)+\".png)\";\n" " \n" " for (i = sOptionCount; i < g_sRowCount; i++)\n" " {\n" " saveSetting('curr'+i, readSetting('curr'+(i+1)));\n" " saveSetting('curr'+(i+1), L_localizedStrings_Text['default'+(i+1)]);\n" " }\n" " \n" " g_sRowCount--;\n" " \n" " // \"Activate\" add link if it was greyed out\n" " if (g_sRowCount <= (g_oCurr.length - 2))\n" " {\n" " addButton.style.display = 'block';\n" " }\n" " saveSetting('rowCount', g_sRowCount);\n" " document.getElementById('currencySelect').size -= 4;\n" " if ( g_oService.IsAvailable )\n" " {\n" " loadSettings();\n" " }\n" "}\n" "////////////////////////////////////////////////////////////////////////////////\n" "//\n" "// Show row deletion button\n" "//\n" "////////////////////////////////////////////////////////////////////////////////\n" "function showDelete(sControlId)\n" "{\n" " if (sControlId != 'curr0' && g_sRowCount > 1)\n" " {\n" " document.getElementById(sControlId + 'DeleteButton').style.display = 'block';\n" " }\n" "}\n" "////////////////////////////////////////////////////////////////////////////////\n" "//\n" "// Hide row deletion button\n" "//\n" "////////////////////////////////////////////////////////////////////////////////\n" "function hideDelete(sControlId)\n" "{\n" " document.getElementById(sControlId + 'DeleteButton').style.display = 'none';\n" "}\n\n" "////////////////////////////////////////////////////////////////////////////////\n" "//\n" "// Show Currency List\n" "//\n" "////////////////////////////////////////////////////////////////////////////////\n" "function showCurrencyList(sControlId)\n" "{\n" " \n" " var currencyList = new Array();\n" " var oSelect = document.getElementById('CurrencySelect');\n" " \n" " // Clear list\n" " oSelect.innerHTML = \"\";\n" " \n" " oSelect.onkeypress = function() {if(event.keyCode == 13){optionsDown(CurrencySelect.options[CurrencySelect.selectedIndex].id);}};\n" " \n" " // Set up function for creating currencyList object\n" " function createCurrency(currSymbol, currText, currTextForSorting)\n" " {\n" " this.currSymbol = currSymbol;\n" " this.currText = currText;\n" " this.currTextForSorting = currTextForSorting;\n" " }\n" " \n" " // Set up sort function\n" " function currencySort(x, y)\n" " {\n" " var xTemp = x.currText;\n" " var yTemp = y.currText;\n" " \n" " if (xTemp > yTemp)\n" " {\n" " return 1;\n" " }\n" " else if (xTemp < yTemp)\n" " {\n" " return -1;\n" " }\n" " else\n" " {\n" " return 0;\n" " }\n" " }\n" " \n" " // Iterate through symbol list returned from currency service and create currencyList\n" " for (x in g_oService.hsCurrencies)\n" " {\n" " var currency = g_oService.hsCurrencies[x];\n" " currencyList.push(new createCurrency(currency.Symbol, getLocalizedString(currency.Symbol), currency.NameForSorting));\n" " }\n" " \n" " // Sort currency list\n" " currencyList.sort(currencySort);\n" " \n" " // Iterate through sorted list and create options\n" " for (var i = 0; i < currencyList.length; i++)\n" " {\n" " var oEachOption = document.createElement('option');\n" " oEachOption.id = sControlId + \"-\" + currencyList[i].currSymbol;\n" " oEachOption.innerText = currencyList[i].currText;\n" " oSelect.appendChild(oEachOption); \n" " }\n" " \n" " //Selecting the current currency\n" " document.getElementById(sControlId + '-' + g_oCurr[sControlId.replace('curr', '')].oTag.Symbol).selected = true;\n" " \n" " // Display the Currency List\n" " var d = document.getElementById('currencyList');\n" " d.style.display = 'block';\n" " CurrencySelect.focus();\n" "}\n" "////////////////////////////////////////////////////////////////////////////////\n" "//\n" "// Close menu when option is selected\n" "//\n" "////////////////////////////////////////////////////////////////////////////////\n" "function optionsDown(sOptionID)\n" "{\n" " saveOptions(sOptionID);\n" " if ( g_oService.IsAvailable )\n" " {\n" " loadSettings();\n" " }\n" " currencyList.style.display = 'none';\n" "}\n" "////////////////////////////////////////////////////////////////////////////////\n" "//\n" "// Save newly selected option\n" "//\n" "////////////////////////////////////////////////////////////////////////////////\n" "function saveOptions(sOptionID)\n" "{\n" " var oOptionID = sOptionID.split('-');\n" " saveSetting(oOptionID[0], oOptionID[1]); \n" " g_oCurr[oOptionID[0].replace('curr', '')].oTextBox.focus();\n" "}\n" "////////////////////////////////////////////////////////////////////////////////\n" "//\n" "// Data for gadget in docked state\n" "//\n" "////////////////////////////////////////////////////////////////////////////////\n" "function DockGadget()\n" "{\n" " var oBody = document.body.style;\n" " oBody.width = '130px';\n" " oBody.height = '83px';\n" " \n" " currencybackground.style.width = 0;\n" " currencybackground.style.height = 0;\n" " currencybackground.src = \"url(images/base-docked.png)\";\n" " \n" " for (var i = g_sRowCount; i > 1; i--)\n" " {\n" " document.getElementById('curr'+i).style.display = 'none';\n" " }\n" " \n" " for (var i=0; i < g_oCurr.length; i++)\n" " {\n" " g_oCurr[i].changeMode('docked');\n" " }\n" " \n" " container.className = 'dockedUIBoundary';\n" " message.className = 'dockedMessage';\n" " \n" " if(document.dir == 'rtl')\n" " {\n" " ageStampText.className = 'ageStampTextDockedModeRtl';\n" " ageStampTextTd.className = 'ageStampTextUndockedModeRtl'\n" " }\n" " else\n" " {\n" " ageStampText.className = 'ageStampTextDockedMode';\n" " ageStampTextTd.className = 'ageStampTextUndockedMode'\n" " }\n" " document.getElementById('ageStampText').innerText = g_ageStampText;\n" " document.getElementById('ageStampText').style.visibility = \"hidden\";\n" " document.getElementById('ageStampTextTd').innerText = g_ageStampText;\n" " document.getElementById('ageStampTextTd').style.visibility = \"hidden\";\n" " \n" " if (g_oService.IsAvailable)\n" " {\n" " if(g_isStaleData)\n" " {\n" " document.getElementById('ageStampText').style.visibility = \"visible\";\n" " }\n" " updateValues(g_oCurr[0].oTextBox, false);\n" " }\n" " bottomTable.style.display = 'none';\n" " addButton.style.display = 'none';\n" "}\n" "////////////////////////////////////////////////////////////////////////////////\n" "//\n" "// Data for gadget in undocked state\n" "//\n" "////////////////////////////////////////////////////////////////////////////////\n" "function UndockGadget()\n" "{\n" " var oBody = document.body.style;\n" " oBody.width = '254px';\n" " oBody.height = (g_sBodyHeight - g_sRowHeight) + (g_sRowCount * g_sRowHeight);\n" " \n" " currencybackground.style.width = 0;\n" " currencybackground.style.height = 0;\n" " currencybackground.src = \"url(images/base-undocked-\"+(g_sRowCount+1)+\".png)\";\n" " \n" " for (var i = g_sRowCount; i > 1; i--)\n" " {\n" " document.getElementById('curr'+i).style.display = 'block';\n" " }\n" " \n" " for (var i=0; i < g_oCurr.length; i++)\n" " {\n" " g_oCurr[i].changeMode('undocked');\n" " }\n" " \n" " container.className = 'UIBoundary';\n" " dataLink.className = 'dataProviderLink';\n" " message.className = 'message';\n" " \n" " if(document.dir == 'rtl')\n" " {\n" " ageStampText.className = 'ageStampTextDockedModeRtl';\n" " ageStampTextTd.className = 'ageStampTextUndockedModeRtl'\n" " }\n" " else\n" " {\n" " ageStampText.className = 'ageStampTextDockedMode';\n" " ageStampTextTd.className = 'ageStampTextUndockedMode'\n" " }\n" " document.getElementById('ageStampText').innerText = g_ageStampText;\n" " document.getElementById('ageStampText').style.visibility = \"hidden\";\n" " document.getElementById('ageStampTextTd').innerText = g_ageStampText;\n" " document.getElementById('ageStampTextTd').style.visibility = \"hidden\";\n" " \n" " if (g_oService.IsAvailable)\n" " {\n" " if(g_isStaleData)\n" " {\n" " document.getElementById('ageStampTextTd').style.visibility = \"visible\";\n" " }\n" " updateValues(g_oCurr[0].oTextBox, false);\n" " bottomTable.style.display = 'block';\n" " if(g_sRowCount<3)\n" " {\n" " addButton.style.display = 'block';\n" " }\n" " \n" " }\n" " \n" " \n" "}\n\n" "////////////////////////////////////////////////////////////////////////////////\n" "//\n" "// Fire update function on keyup\n" "//\n" "////////////////////////////////////////////////////////////////////////////////\n" "function OnAmountChange()\n" "{\n" " var sourceTextBox = event.srcElement;\n\n" " updateValues(sourceTextBox, true);\n" "}\n" "////////////////////////////////////////////////////////////////////////////////\n" "//\n" "// Update currency field values\n" "//\n" "////////////////////////////////////////////////////////////////////////////////\n" "function updateValues(sourceTextBox,bSkipCurrent)\n" "{ \n" " if (g_oService.IsAvailable)\n" " {\n" " // Get the currency object that goes with this text box\n" " var sourceCurrency = g_oCurr[sourceTextBox.getAttribute('arrayIdx')];\n" " \n" " var oCurrency;\n" " \n" " for (var i=0; i < g_oCurr.length; i++)\n" " {\n" " oCurrency = g_oCurr[i];\n" " \n" " // skip the box where the text changed.\n" " if(bSkipCurrent)\n" " {\n" " if (sourceTextBox != oCurrency.oTextBox)\n" " {\n" " try\n" " {\n" " oCurrency.oTextBox.value = g_oService.Convert(sourceTextBox.value, sourceCurrency.oTag.Symbol, oCurrency.oTag.Symbol);\n" " }\n" " catch(objError)\n" " {\n" " oCurrency.oTextBox.value = getLocalizedString('Error');\n" " }\n" " }\n" " }\n" " else\n" " {\n" " try\n" " {\n" " oCurrency.oTextBox.value = g_oService.Convert(sourceTextBox.value, sourceCurrency.oTag.Symbol, oCurrency.oTag.Symbol);\n" " }\n" " catch(objError)\n" " {\n" " oCurrency.oTextBox.value = getLocalizedString('Error');\n" " }\n" " }\n" " \n" " }\n" " }\n" "}\n" "////////////////////////////////////////////////////////////////////////////////\n" "//\n" "// Set UI state\n" "//\n" "////////////////////////////////////////////////////////////////////////////////\n" "function SetUIState(sState)\n" "{\n" " function ShowMessage(sMessage)\n" " {\n" " showOrHide('container', false);\n" " showOrHide('message', true); \n" " \n" " }\n" " document.getElementById('bottomTable').style.display = 'none';\n" " \n" " document.getElementById('ageStampText').innerText = g_ageStampText;\n" " document.getElementById('ageStampText').style.visibility = \"hidden\";\n" " document.getElementById('ageStampTextTd').innerText = g_ageStampText;\n" " document.getElementById('ageStampTextTd').style.visibility = \"hidden\";\n" " \n" " spinner.stop();\n" " switch(sState)\n" " {\n" " \n" " case 'loading':\n" " \n" " spinner.show();\n" " spinner.start();\n" " document.getElementById('messageSpinner').style.display = 'inline';\n" " document.getElementById('messageIcon').style.display = 'none';\n" " ShowMessage(getLocalizedString('WaitText'));\n" " document.getElementById('messageText').innerHTML = getLocalizedString('WaitText');\n" " break;\n" " \n" " case 'error':\n" " \n" " document.getElementById('messageIcon').style.display = 'inline';\n" " document.getElementById('messageSpinner').style.display = 'none';\n" " ShowMessage(getLocalizedString('ServiceNotAvailable'));\n" " if(document.dir == 'rtl')\n" " {\n" " document.getElementById('messageText').innerHTML = getLocalizedString('ServiceNotAvailable');\n" " document.getElementById('messageText').style.textAlign = 'right';\n" " }\n" " else\n" " {\n" " document.getElementById('messageText').innerHTML = getLocalizedString('ServiceNotAvailable');\n" " document.getElementById('messageText').style.textAlign = 'left';\n" " }\n" " break;\n" " \n" " case 'ready':\n" " showOrHide('container', true);\n" " showOrHide('message', false);\n" " if (!System.Gadget.docked)\n" " {\n" " document.getElementById('bottomTable').style.display = 'block';\n" " } \n" " break;\n" " \n" " case 'cached':\n" " showOrHide('container', true);\n" " showOrHide('message', false);\n" " if (!System.Gadget.docked)\n" " {\n" " document.getElementById('bottomTable').style.display = 'block';\n" " document.getElementById('ageStampTextTd').style.visibility = \"visible\";\n" " } \n" " else\n" " {\n" " document.getElementById('ageStampText').style.visibility = \"visible\";\n" " }\n" " break;\n" " }\n" "}\n" "////////////////////////////////////////////////////////////////////////////////\n" "//\n" "// Check for availability of data\n" "//\n" "////////////////////////////////////////////////////////////////////////////////\n" "function DataReady(data)\n" "{\n" " var milliSecondsToNextQuery;\n" " \n" " g_dataFromService = data;\n" " g_isStaleData = false;\n" " g_ageStampText = \"\";\n" " \n" " if (g_oTimer != null)\n" " clearTimeout(g_oTimer);\n\n" " if ((data != null) && g_oService.IsAvailable && (data.Count > 0) && ((data.RetCode == 200) || (data.RetCode == 1507)))\n" " {\n" " if (data.RetCode == 200)\n" " {\n" " var serviceRefreshInterval;\n" " \n" " gTimeStampLastRefreshAvailable = true;\n" " gTimeStampLastRefresh = data.Timestamp;\n\n" " SetUIState('ready');\n" " loadSettings();\n" " \n" " serviceRefreshInterval = g_oService.RefreshInterval();\n" " if (serviceRefreshInterval != -1)\n" " {\n" " // Update the UI after refresh interval\n" " milliSecondsToNextQuery = 1000 * 60 * serviceRefreshInterval;\n" " }\n" " else\n" " {\n" " // Update the UI in 1 minute\n" " milliSecondsToNextQuery = 1000 * 60;\n" " }\n" " }\n" " else\n" " {\n" " g_isStaleData = true;\n" " g_ageStampText = calculateAgeStampText(calculateAge(data.Timestamp));\n" " SetUIState('cached');\n" " loadSettings();\n" " // Update the UI in 1 minute\n" " milliSecondsToNextQuery = 1000 * 60;\n" " }\n" " }\n" " else\n" " {\n" " SetUIState('error');\n" " // Try again in 1 minute\n" " milliSecondsToNextQuery = 1000 * 60;\n" " }\n" " \n" " g_oTimer = setTimeout('g_oService.GetCurrencies()', milliSecondsToNextQuery);\n" "}\n" "////////////////////////////////////////////////////////////////////////////////\n" "//\n" "// Load currency symbols for each currency row\n" "//\n" "////////////////////////////////////////////////////////////////////////////////\n" "function loadSettings()\n" "{\n" " \n" " for (i = 0; i < g_oCurr.length; i++)\n" " {\n" " var sCurr = readSetting('curr'+i) || L_localizedStrings_Text['default'+i];\n" " saveSetting('curr'+i, sCurr);\n" " \n" " g_oCurr[i].oTag = g_oService.hsCurrencies[sCurr];\n" " \n" " //Get first available if list of currency is not complete\n" " if(g_oCurr[i].oTag == undefined)\n" " {\n" " sCurr = g_dataFromService.Item(0).Symbol;\n" " g_oCurr[i].oTag = g_oService.hsCurrencies[sCurr]; \n" " } \n" " \n" " if (g_sFullName){\n" " g_oCurr[i].setCaption(g_oService.hsCurrencies[sCurr].Name);\n" " } else {\n" " g_oCurr[i].setCaption(g_oCurr[i].oTag.Symbol);\n" " }\n" " \n" " var sURLLocale = '';\n" " if (g_oCurr[i].oTag.Symbol != 'USD')\n" " {\n" " sURLLocale = g_oCurr[i].oTag.Symbol;\n" " }\n" " document.getElementById('curr'+i+'OnlineButtonA').href = getLocalizedString('CurrencyLink')+sURLLocale+'USD';\n" " \n" " }\n" " \n" " updateValues(g_oCurr[0].oTextBox, false);\n" "}\n" "////////////////////////////////////////////////////////////////////////////////\n" "//\n" "// Handle ESCAPE and ENTER keydown\n" "//\n" "////////////////////////////////////////////////////////////////////////////////\n" "function OnKeyDownHandler()\n" "{\n" " if(event.keyCode == 27)//ESCAPE key\n" " {\n" " document.getElementById('currencyList').style.display = 'none'; \n" " } \n" "}\n\n" "////////////////////////////////////////////////////////////////////////////////\n" "//\n" "// Spinner Animation\n" "//\n" "////////////////////////////////////////////////////////////////////////////////\n" "function getSpinner( spinnerDivID ) \n" "{\n" " var self = this;\n" " this.id = spinnerDivID;\n" " this.parentDiv = document.getElementById( self.id );\n" " this.fps = 1000/30; \n" " with (this.parentDiv.style) {\n" " fontSize=0;\n" " posWidth=16;\n" " posHeight=16;\n" " backgroundImage = 'url(\"images/activity16v.png\")';\n" " backgroundPositionY = 0;\n" " }\n" " this.hide = function() { self.parentDiv.style.display='none'; }\n" " this.show = function() { self.parentDiv.style.display='block'; }\n" " this.stop = function() { clearInterval( self.animationInterval ); }\n" " this.start = function() {\n" " clearInterval( self.animationInterval );\n" " this.animationInterval = setInterval( 'animate(' + self.id + ')', 30 );\n" " }\n" "} \n\n" "function animate(spinnerDiv) \n" "{\n" " spinnerDiv.style.backgroundPositionY=parseInt(spinnerDiv.style.backgroundPositionY)-16; \n" "}\n\n" "////////////////////////////////////////////////////////////////////////////////\n" "//\n" "// Handle RightClick\n" "//\n" "////////////////////////////////////////////////////////////////////////////////\n" "function OnRightClickHandler()\n" "{\n" " if(event.srcElement.tagName != 'INPUT')\n" " {\n" " if(event.button > 1)\n" " {\n" " var selectedText = document.getElementById('curr0input').createTextRange();\n" " selectedText.moveStart('character', document.getElementById('curr0input').value.length); \n" " selectedText.select();\n" " event.srcElement.focus(); \n" " }\n" " }\n" " return true;\n" "}\n\n" "function calculateAge ( timestamp )\n" "{\n" " var timestampDay = new Date( timestamp );\n" " var currentDay = new Date();\n" " \n" " var millisecondsTillTimestamp = Date.parse( timestamp );\n" " var millisecondsTillNow = (new Date()).getTime();\n" " var minutesDifference = parseInt( ( millisecondsTillNow - millisecondsTillTimestamp ) / ( 60 * 1000 ) );\n" " var hoursDifference = parseInt ( minutesDifference / 60 );\n" " var daysDifference = parseInt ( hoursDifference / 24 );\n" " \n" " this.minutesAge = 0;\n" " this.hoursAge = 0;\n" " this.daysAge = 0;\n" " \n" " if ( minutesDifference <= 0 )\n" " {\n" " return this;\n" " }\n\n" " // shows hours and mins only for the same day\n" " if ( timestampDay.getDate() == currentDay.getDate()\n" " && timestampDay.getMonth() == currentDay.getMonth()\n" " && timestampDay.getFullYear() == currentDay.getFullYear() )\n" " {\n" " this.minutesAge = minutesDifference % 60;\n" " this.hoursAge = hoursDifference % 24;\n" " this.daysAge = daysDifference;\n" " }\n" " else // only calculate total no of days past\n" " {\n" " timestampDay.setHours(currentDay.getHours(),currentDay.getMinutes(),currentDay.getSeconds(),currentDay.getMilliseconds());\n" " this.daysAge = parseInt ( ( currentDay.getTime() - timestampDay.getTime() ) / ( 60 * 1000 * 60 * 24 ) );\n" " if ( this.daysAge < 0 )\n" " {\n" " this.daysAge = 0;\n" " }\n" " }\n" " \n" " return this;\n" "}\n\n" "function calculateAgeStampText( age )\n" "{\n" " var ageStampText = \"\";\n" " var unitText = \"\";\n" " var durationText = \"\";\n" " \n" " if ( age.daysAge > 0 )\n" " {\n" " durationText = getLocalizedString('day');\n" " if ( age.daysAge > 1 )\n" " {\n" " durationText = getLocalizedString('days');\n" " }\n" " unitText = age.daysAge;\n" " }\n" " else if ( age.hoursAge > 0 )\n" " {\n" " durationText = getLocalizedString('hr');\n" " if ( age.hoursAge > 1 )\n" " {\n" " durationText = getLocalizedString('hrs');\n" " }\n" " unitText = age.hoursAge;\n" " }\n" " else\n" " {\n" " if ( age.minutesAge != 0 )\n" " {\n" " durationText = getLocalizedString('min');\n" " unitText = age.minutesAge;\n" " }\n" " }\n" " \n" " if((unitText != \"\") && (durationText != \"\"))\n" " {\n" " ageStampText = getLocalizedString('ageStampMessage')\n" " ageStampText = ageStampText.replace(\"%1\", unitText);\n" " ageStampText = ageStampText.replace(\"%2\", durationText);\n" " }\n" " \n" " return ageStampText;\n" "}\n") subst = "$2" # You can manually specify the number of replacements by changing the 4th argument result = re.sub(regex, subst, test_str, 0) if result: print (result) # Note: for Python 2.7 compatibility, use ur"" to prefix the regex and u"" to prefix the test string and substitution.

Please keep in mind that these code samples are automatically generated and are not guaranteed to work. If you find any syntax errors, feel free to submit a bug report. For a full regex reference for Python, please visit: https://docs.python.org/3/library/re.html