-1

The output should be like;

Hans4444müller ---> HansIVmüller

Mary555kren ---> MaryVkren

Firstly I have tried to get all repetitive numbers from a word with that regex:

(\d)\1+ // and replace that with $1

After I get the repetitive number such as 4, I tried to change this number to IV but unfortunately I can't find the correct regex for this. What I think about this algorithm is if there is a repeating number, replace that number with the roman form.

Are there any possible way to do it with regex ?

Codeisacode
  • 37
  • 1
  • 7

1 Answers1

0

I don't know Java very well, but I do know regular expressions, C# and JavaScript. I am confident you can adapt one of my techniques to Java.

I have sample code with two different techniques.

  1. The first invokes a function on every match to perform the replacement
  2. The second iterates the matches provided by your regular expression you and convert each match into Roman numerals, then injects the result into your original text.

The link below illustrates technique 1 using DotNetFiddle. The replacement function takes a method name. The method in question performs is invoked for every match. This technique requires very little code. https://dotnetfiddle.net/o9gG28. If you're lucky, Java has a similar technique available.

Technique 2: a javascript version that loops through every match found by the regex: https://jsfiddle.net/ActualRandy/rxnzoc3u/81/. The method does some string concatenation using the replacement value.

Here's some code for method 2 using .NET syntax, Java should be similar. The key methods are 'Match' and 'GetNextMatch'. Match uses your regex to get the first match.

private void btnRegexRep_Click(object sender, RoutedEventArgs e) {
    string fixThis = @"Hans4444müller,Mary555kren";
    var re = new Regex("\\d+");

    string result = "";
    int lastIndex = 0;
    string lastMatch = "";
    //Get the first match using the regular expression:
    var m = re.Match(fixThis);

    //Keep looping while we can match:
    while (m.Success) {
        //Get length of text between last match and current match:
        int len = m.Index - (lastIndex + lastMatch.Length);
        result += fixThis.Substring(lastIndex + lastMatch.Length, len) + GetRomanText(m);

        //Save values for next iteration:
        lastIndex = m.Index;
        lastMatch = m.Value;
        m = m.NextMatch();
    }

    //Append text after last match:
    if (lastIndex > 0) {
        result += fixThis.Substring(lastIndex + lastMatch.Length);
    }

    Console.WriteLine(result);
}

private string GetRomanText(Match m) {
    string[] roman = new[] { "I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX", "IX" };
    string result = "";
    // Get ASCII value of first digit from the match (remember, 48= ascii 0, 57=ascii 9):
    char c = m.Value[0];
    if (c >= 48 && c <= 57) {
        int index = c - 48;
        result = roman[index];
    }

    return result;
}
ActualRandy
  • 180
  • 1
  • 8
  • 1
    Thank you so much for your effort and and interest. I've applied the first technique and It's working. I just need to find something to replace m.Value[0]. – Codeisacode Oct 22 '19 at 20:35
  • You're welcome, it was fun. I should note that the syntax 'm.Value[0]' serves to retrieve the 0th (i.e. first) character in the match string, Java potentially has a function along the lines of 'getChar' which accomplishes the same thing. – ActualRandy Oct 25 '19 at 16:43