Find and Replace multiple strings in c# with or without regex - javascript

I need some help with my code. What i am trying to do is find one string at a time in a sentence and replace the same string with a span tag.
I have achieved same with javascript but I am unsure of how to do it in C#
Code in js:
//this function takes 'buffer' as content &
//search query (multiple string values) as replaceStrings and highlights the query
function highlitor(buffer, replaceStrings)
{
var highlightedText = buffer;
for (var i = 0; i < replaceStrings.length; i++)
{
var exp = new RegExp("(" + replaceStrings[i] + ")", "gi");
highlightedText = highlightedText.replace(exp, "<span class='highlight-search-text'>$1</span>");
}
return highlightedText;
}
For example
buffer=" This is an exciting and enhansive test" replaceStrings=[exciting,enhace];
highlightedText="This is an <span class='highlight-text'>exciting</span> and <span class='highlight-text'>enhansive</span> test"
Thanks in advance.

I think you just need String.Replace in a loop:
public static string Highlitor(string text, IEnumerable<string> replaceStrings)
{
string result = text;
foreach(string repl in replaceStrings.Distinct())
{
string replWith = string.Format("<span class='highlight-text'>{0}</span>", repl);
result = result.Replace(repl, replWith);
}
return result;
}
You don't need Distinct if the list doesn't contain duplicates.
UPDATE: as it seems things are much more complicated. You want to replace parts by preserving the original case when the pattern is part of the final replacement string.
Here is a modified version of my above method that uses an extended version of String.Replace:
public static string Highlitor(string text, IEnumerable<string> replaceStrings)
{
string result = text;
foreach (string repl in replaceStrings.Distinct())
{
string replWith = string.Format("<span class='highlight-text'>{0}</span>", repl);
result = ReplaceCaseInsensitive(result, repl, replWith, true);
}
return result;
}
Here is the method that replaces strings case-insensitively and supports keeping the original case:
public static string ReplaceCaseInsensitive(string original, string pattern, string replacement, bool keepOriginalCase = false)
{
int count, position0, position1;
count = position0 = position1 = 0;
int replacementIndexOfPattern = replacement.IndexOf(pattern, StringComparison.OrdinalIgnoreCase);
if (replacementIndexOfPattern == -1)
keepOriginalCase = false; // not necessary
int inc = (original.Length / pattern.Length) *
(replacement.Length - pattern.Length);
char[] chars = new char[original.Length + Math.Max(0, inc)];
bool[] upperCaseLookup = new bool[pattern.Length];
while ((position1 = original.IndexOf(pattern, position0, StringComparison.OrdinalIgnoreCase)) != -1)
{
// first part that will not be replaced
for (int i = position0; i < position1; ++i)
chars[count++] = original[i];
// remember the case of each letter in the found patter that will be replaced
if (keepOriginalCase)
{
for (int i = 0; i < pattern.Length; ++i)
upperCaseLookup[i] = Char.IsUpper(original[position1 + i]);
}
// The part that will be replaced:
for (int i = 0; i < replacement.Length; ++i)
{
// only keep case of the relevant part of the replacement that contains the part to be replaced
bool lookupCase = keepOriginalCase
&& i >= replacementIndexOfPattern
&& i < replacementIndexOfPattern + pattern.Length;
char newChar = replacement[i];
if (lookupCase)
{
bool wasUpper = upperCaseLookup[i - replacementIndexOfPattern];
bool isUpper = Char.IsUpper(newChar);
if (wasUpper && !isUpper)
newChar = Char.ToUpperInvariant(newChar);
else if (!wasUpper && isUpper)
newChar = Char.ToLowerInvariant(newChar);
}
else
{
newChar = replacement[i];
}
chars[count++] = newChar;
}
position0 = position1 + pattern.Length;
}
if (position0 == 0)
return original;
// the rest
for (int i = position0; i < original.Length; ++i)
chars[count++] = original[i];
return new string(chars, 0, count);
}
It's algorithm based on: Fastest C# Case Insenstive String Replace.

I got the functionality as :
for (var j = 0; j < searchTermArray.Length; j++)
{
CompareInfo ci = CultureInfo.CurrentCulture.CompareInfo;
int indexOfTerm = ci.IndexOf(text, searchTermArray[j], CompareOptions.IgnoreCase);
//dont replace if there is no search term in text
if(indexOfTerm!= -1)
{
string subStringToHighlight = text.Substring(indexOfTerm, searchTermArray[j].Length);
//replacing with span
string replaceWith = string.Format("<span class='highlight-search-text'>{0}</span>", subStringToHighlight);
text = Regex.Replace(text, searchTermArray[j], replaceWith, RegexOptions.IgnoreCase);
}
}

Related

Write a Optimal program to remove numbers from a string and then result string should be reversed

Write a Optimal program to remove numbers from a string and then result string should be reversed for e.g Input = "A1B2" Output = "BA" in any language
the program which i came up with is this
var str = "A1B2";
var temp = "";
for(var i = str.length - 1; i >= 0; i--) {
if(!(str[i] >= 0 && str[i] <= 9))
temp += str[i]
}
var str = "A1B2"
str.split('').reverse().join('').replace(/[0-9]/g, '')
As you mentioned, You need answer in any language.
In java,
String str="A1B2";
String answer = new StringBuilder(str.replaceAll("[0-9]","")).reverse().toString();
System.out.println(answer);
You start at the last position of the input and check if it is a number, if it is, then skip it, otherwise, add it.
public static void main(String[] args) throws IOException {
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
String input = reader.readLine();
String newWord = "";
for (int i = input.length() - 1; i >= 0; i--) {
if (input.charAt(i) < '0' || input.charAt(i) > '9') {
newWord += input.charAt(i);
}
}
System.out.println(newWord);
}
Input:
B224SA54ABCR
Output:
RCBAASB
You should iterate char by char in your string and detect wether the current char is a letter or not, may be by using ASCII table. The reserving will be done by iterating from the end on the string to the beginning as you did in the shown code. At least this is what I would do in C, but other easier ways exist in java.
You should not use temp += ""if temp has not been initialized prior. I cannot recommend you any method or function to do so " in an optimal way since it depends on the language.
Here is a possible C solution :
#include <stdio.h>
#include <string.h>
#include <ctype.h>
char line[128] = "A1B2C9C841630ERV221";
char res[128] = "";
for (int i = strlen(line) -1; i >= 0; --i)
{
if (isalpha(line[i]))
{
char currentChar[2];
currentChar[1] = 0;
currentChar[0] = line[i];
strcat(res, currentChar);
}
}
printf("%s\n", res);
Output : VRECCBA
Only thing you should care of is the size of line and res which I set to 128 which might not be enough depending of the length of the string you input.

How to alternate the case of a string

I'm working on alternating the case of a string (for example asdfghjkl to AsDfGhJkL).
I tried to do this. I found some code that is supposed to do it, but it doesn't seem to be working.
var str="";
var txt=document.getElementById('input').value;
for (var i=0; i<txt.length; i+2){
str = str.concat(String.fromCharCode(txt.charCodeAt(i).toUpperCase()));
}
Here's a quick function to do it. It makes the entire string lowercase and then iterates through the string with a step of 2 to make every other character uppercase.
var alternateCase = function (s) {
var chars = s.toLowerCase().split("");
for (var i = 0; i < chars.length; i += 2) {
chars[i] = chars[i].toUpperCase();
}
return chars.join("");
};
var txt = "hello world";
console.log(alternateCase(txt));
HeLlO WoRlD
The reason it converts the string to an array is to make the individual characters easier to manipulate (i.e. no need for String.prototype.concat()).
Here an ES6 approach:
function swapCase(text) {
return text.split('').map((c,i) =>
i % 2 == 0 ? c.toLowerCase() : c.toUpperCase()
).join('');
}
console.log(swapCase("test"))
You should iterate the string and alternate between upper-casing the character and lower-casing it:
for (var i=0; i<txt.length; i++) {
var ch = String.fromCharCode(txt.charCodeAt(i);
if (i % 2 == 1) {
ch = ch.toUpperCase();
} else {
ch = ch.toLowerCase();
}
str = str.concat(ch);
}

How to convert a floating point number to Base36 in C# in the same way as JavaScript's .toString(36) does it

I am trying to convert some code to the C# (from the JavaScript), I need to convert a double number(0.04036483168558814) to ".toString(36)/Base36" by C#.
JavaScript code here:
var num = 0.04036483168558814;
var n = num.toString(36);
Output(n) below :
0.1gb9f0lx08ij9wwfwkyk5d0a4i
I need this same above result by C#, so how I will get this same results in C# ??
I applied some code, but they are not working..
My code below(by C#) :
1)
string OutputVal = Convert.ToString(Int64.Parse("0.04036483168558814"), 36);
or
string OutputVal = Convert.ToString(Int64.Parse("0.04036483168558814".Substring(2)), 36);
2)
private const string CharList = "0123456789abcdefghijklmnopqrstuvwxyz";
public static String Encode(long input)
{
if (input < 0) throw new ArgumentOutOfRangeException("input", input, "input cannot be negative");
char[] clistarr = CharList.ToCharArray();
var result = new Stack<char>();
while (input != 0)
{
result.Push(clistarr[input % 36]);
input /= 36;
}
return new string(result.ToArray());
}
string OutputString = Encode(Int64.Parse("0.04036483168558814"));
or
string OutputString = Encode(Int64.Parse("0.04036483168558814".Substring(2)));
According to MSDN, you can use Convert.ToString method in order to convert integer number to a string representation in base 2, 8, 10 or 16.
If you want to convert the number to a base 36, you can either use existing third-party libraries:
Check this CodeProject article or this GitHub project out.
Or you can write your own converter.
For example, this class converts integers to Base 36:
public static class Base36Converter
{
private const int Base = 36;
private const string Chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
public static string ConvertTo(int value)
{
string result = "";
while (value > 0)
{
result = Chars[value % Base] + result; // use StringBuilder for better performance
value /= Base;
}
return result;
}
}
Note that result will be in big-endian order.
For example, decimal 1296 will be 100 in base-36.
I wrote some code to get this result.
Here's the code :
//==========================================
string Results = Encode(0.04036483168558814);
//==========================================
private string Encode(double input)
{
var result = new Stack<char>();
char[] clistarr = "0123456789abcdefghijklmnopqrstuvwxyz".ToCharArray();
Int64 inputValInt = 0;
string inputValP = "";
double inputValN = 0;
string ReturnsVal = "";
if (input.ToString() != "")
{
try
{
if (input.ToString().Contains("."))
{
inputValP = input.ToString().Substring(0, input.ToString().IndexOf("."));
inputValInt = Int64.Parse(inputValP);
if (inputValInt != 0)
{
while (inputValInt != 0)
{
result.Push(clistarr[inputValInt % 36]);
inputValInt /= 36;
}
char[] RevArr1 = result.ToArray();
Array.Reverse(RevArr1);
result = new Stack<char>();
for (int i = (RevArr1.Length - 1); i >= 0; i--)
{
result.Push(RevArr1[i]);
}
result.Push('.');
}
else
{
result.Push('0');
result.Push('.');
}
inputValN = input - inputValInt;
double inputVal = inputValN;
int CountLoop = 0;
while (CountLoop < 11)
{
double tempVal = (inputVal * 36);
int Start = tempVal.ToString("R").IndexOf(".");
if (Start > 0)
{
inputValP = tempVal.ToString("R").Substring(0, Start);
int TopVal = Int16.Parse(inputValP);
result.Push(clistarr[TopVal]);
inputVal = tempVal - TopVal;
}
CountLoop++;
}
char[] RevArr = result.ToArray();
Array.Reverse(RevArr);
ReturnsVal = new string(RevArr);
}
else
{
inputValInt = Convert.ToInt64(input);
while (inputValInt != 0)
{
result.Push(clistarr[inputValInt % 36]);
inputValInt /= 36;
}
char[] RevArr = result.ToArray();
ReturnsVal = new string(RevArr);
}
}
catch (Exception ee)
{
return ("");
}
}
else
{
return ("");
}
return (ReturnsVal);
}
Here is a recursive function:
using System;
class Program {
static string encode(int nIn, int nBase) {
int n = nIn / nBase;
char c = "0123456789abcdefghijklmnopqrstuvwxyz"[nIn % nBase];
return n > 0 ? encode(n, nBase) + c : c.ToString();
}
static void Main() {
var n = 1577858399;
var s = encode(n, 36);
Console.WriteLine(s == "q3ezbz");
}
}
Thanks to user2032344 answer, I finally managed to get the same result as Javascript Math.random().toString(36) in C++/Qt
static QString JSMathRandomToString36(double input)
{
static const auto clistarr = QByteArray("0123456789abcdefghijklmnopqrstuvwxyz");
QString result;
for(auto i = 0; i < 11 ; i++){
auto tempVal = (input * 36);
auto tempValStr = QString::number(tempVal, 'R');
auto decIndex = tempValStr.indexOf(".");
if (decIndex > 0) {
auto topVal = tempValStr.mid(0, decIndex).toShort();
result.append(clistarr[topVal]);
input = tempVal - topVal;
}
}
return (result);
}

Simply XOR encrypt in Javascript and Decrypt in Java

The purpose for this is not highly security-relevant and the key will be long, so I'm just wanting to use simple XOR encryption to the strings.
Well, the Javascript on the client is as follows:
function dc_encrypt(str, key)
{
var ord = []; var res = "";
var i;
for (i = 1; i <= 255; i++) {ord[String.fromCharCode(i)] = i}
for (i = 0; i < str.length; i++)
res += String.fromCharCode(ord[str.substr(i, 1)] ^ ord[key.substr(i % key.length, 1)]);
return(res);
}
And the Java is is:
public String dc_decrypt(String str, String key)
{
StringBuilder sb = new StringBuilder();
for(int i = 0; i < str.length(); i++)
sb.append((char)(str.charAt(i) ^ key.charAt(i % (key.length()))));
return(sb.toString());
}
Unfortunately this produces some very weird results. Some letters differ after encrypting in JS, sending the result through a POST and decrypt in Java.
In every case it doesn't seem to be reliable.
I assume the issue must have something to do with encoding... does someone know a more reliable solution for this?
Huge thanks in advance! :)
When XOR-encoding two strings, the resulting XOR-values of the individual characters sometimes do not result in characters that can be displayed.
Therefore one solution is to encode the result as a sequence of hex-values and then to decode these hex-values on the server side.
Javascript:
function encryptStringWithXORtoHex(input,key) {
var c = '';
while (key.length < input.length) {
key += key;
}
for(var i=0; i<input.length; i++) {
var value1 = input[i].charCodeAt(0);
var value2 = key[i].charCodeAt(0);
var xorValue = value1 ^ value2;
var xorValueAsHexString = xorValue.toString("16");
if (xorValueAsHexString.length < 2) {
xorValueAsHexString = "0" + xorValueAsHexString;
}
c += xorValueAsHexString;
}
return c;
}
Java-Code:
private static String decryptStringWithXORFromHex(String input,String key) {
StringBuilder c = new StringBuilder();
while (key.length() < input.length()/2) {
key += key;
}
for (int i=0;i<input.length();i+=2) {
String hexValueString = input.substring(i, i+2);
int value1 = Integer.parseInt(hexValueString, 16);
int value2 = key.charAt(i/2);
int xorValue = value1 ^ value2;
c.append(Character.toString((char) xorValue));
}
return c.toString();
};
Example:
Encode in Javascript:
encryptStringWithXORtoHex('Encrypt This','SecretKey');
returns the string 160b00001c043f452d3b0c10
Decrypting in Java:
decryptStringWithXORFromHex("160b00001c043f452d3b0c10","SecretKey")
returns Encrypt This
Please note: the shown solution only works for characters that have a charChode value of less or equal than 255. If you want to use the solution for unicode characters (e.g. €) you will have to change the code to take care of this.

List Permutations

I'm trying to list all three letter permutations and this is the code I have -
window.permute = function(){
var alphabet = "abcdefghijklmnopqrstuvwxyz";
var searchTerm ="aaa";
var position = 2;
changeString(searchTerm, position);
}
window.changeString = function(searchTerm, position){
if (position <0){
alert(newString);
return;
}
var alphabet = "abcdefghijklmnopqrstuvwxyz"
for (j=0; j < 26;j++){
var newString = searchTerm.substr(0, position) + alphabet[j] + searchTerm.substr(position+1);
var newPosition = position -1;
changeString(newString,newPosition);
}
return;
}
It's not working and I'm not sure why- can anyone help?
var permutate = (function() {
var results = [];
function doPermute(input, output, used, size, level) {
if (size == level) {
var word = output.join('');
results.push(word);
return;
}
level++;
for (var i = 0; i < input.length; i++) {
if (used[i]) {
continue;
}
used[i] = true;
output.push(input[i]);
doPermute(input, output, used, size, level);
used[i] = false;
output.pop();
}
}
return {
getPermutations: function(input, size) {
var chars = input.split('');
var output = [];
var used = new Array(chars.length);
doPermute(chars, output, used, size, 0);
return results;
}
}
})();
for more information, visit http://jinwolf.tumblr.com/post/26476479113/draw-something-cheat
for an working example, check this jsfiddle http://jsfiddle.net/jinwolf/Ek4N5/31/
alert(newString);
newString is not defined right there. Instead, you should use the argument passed:
alert(searchTerm);
Edit: I'm not entirely sure of your approach. It seems overly complicated. This seems to work. I understand that you rather have your own code working, but perhaps this helps you in solving. I don't quite get your substr part.
http://jsfiddle.net/NUG2A/2/
var alphabet = "abc"; // shortened to save time
function permute(text) {
if(text.length === 3) { // if length is 3, combination is valid; alert
console.log(text); // or alert
} else {
var newalphabet = alphabet.split("").filter(function(v) {
return text.indexOf(v) === -1;
}); // construct a new alphabet of characters that are not used yet
// because each letter may only occur once in each combination
for(var i = 0; i < newalphabet.length; i++) {
permute(text + newalphabet[i]); // call permute with current text + new
// letter from filtered alphabet
}
}
}
permute("");
This will result in the following being called:
permute("");
permute("a");
permute("ab");
permute("abc"); // alert
permute("ac");
permute("acb"); // alert
permute("b");
// ...
I'm not sure from your question that you mean "permutations" because usually permutations do not include repeated elements where it looks like you want to include "aaa".
Here are several algorithms for listing permutations you can go check out. If it turns out you mean to have repetitions, it looks like pimvdb has you covered.
Edit: So you know what you are getting into run-time wise:
With repetition (aaa,aab,...): n^k = 26^3 = 17,576
Without repetition (abc,bac,...): n!/(n-k)! = 26!/(26-3)! = 15,600
for (j=0; j < 26;j++){
should be
for (var j=0; j<26; j++) {
Without the declaration, j is a global variable, so it only takes one iteration to get to 26 and then all the loops terminate.
For permutations a recursive algorith as pimvd showed is always nice but don't forget you can just brute force it with for-loops when N is small:
for(int x1=0; x1 < 26; x1++)
for(int x2=0; x2 < 26; x2++)
for(int x3=0; x3 < 26; x3++){
//do something with x1, x2, x3
}
In C#:
void DoPermuation(string s)
{
var pool = new HashSet<string>();
//Permute("", , pool);
pool = Permute(new List<char>(s));
int i = 0;
foreach (var item in pool) Console.WriteLine("{0:D2}: {1}", ++i, item);
}
HashSet<string> Permute(List<char> range)
{
if (range.Count == 1) return new HashSet<string>(new string[] { range[0].ToString() });
var pool = new HashSet<string>();
foreach (var c in range)
{
var list = new List<char>(range);
list.Remove(c);
foreach (var item in Permute(list)) pool.Add(c + item);
}
return pool;
}

Categories