HiveBrain v1.2.0
Get Started
← Back to all entries
patterncsharpMinor

Find tags in text for replacement, my brute force solution

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
forcetexttagsforfindbrutesolutionreplacement

Problem

I have a text such as

string text = "Hi [img-2] tst[img-3] test ttteessstt grawr[img-1-800]tet";


I want to find img tags in the text and get their id (second value) and possibly the third value if it exists.

string text = "Hi [img-2] tst[img-3] test ttteessstt grawr[img-1-800]tet";

var th = new TagHandler(null);
var res = th.FindImgTags(text);

foreach(var tag in res)
{
    Debug.WriteLine(string.Join(", ", tag.Tag, tag.Id, tag.Width));
}


The above code outputs this:

[img-2], 2, 0
[img-3], 3, 0
[img-1-800], 1, 800


This is my "find tags code". Its crude but gets the job done...
Any suggestions on how to make this less verbose / brute

public List FindImgTags(string data)
{
    var result = new List();

    var pieces = data.Split(new string[] { "[img-" }, StringSplitOptions.RemoveEmptyEntries);
    foreach (var item in pieces)
    {
        if (item.Contains(']'))
        {
            var backend = item.Split(new char[] { ']' }, StringSplitOptions.RemoveEmptyEntries);
            var dataInside = backend[0];

            var r = new ImgReplaceItem();
            r.Tag = "[img-" + dataInside + "]";
            var pid = -1;
            if (dataInside.Contains('-'))
            {
                var widthParts = dataInside.Split(new char[] { '-' }, StringSplitOptions.RemoveEmptyEntries);
                int.TryParse(widthParts[0], out pid);

                if (widthParts.Count() > 1)
                {
                    var width = -1;
                    int.TryParse(widthParts[1], out width);
                    r.Width = width;
                }
            }
            else
            {
                int.TryParse(dataInside, out pid);
            }
            r.Id = pid;
            result.Add(r);
        }
    }

    return result;
}

Solution

This is a lot of code for such a simple task... but how about some regex:

string text = "Hi [img-2] tst[img-3] test ttteessstt grawr[img-1-800]tet";

var ids = Regex.Matches(
     text, 
     @"\[(?[a-z]+)-(?\d+)(-(?\d+))?\]",
     RegexOptions.IgnoreCase | RegexOptions.ExplicitCapture
)
.Cast()
.Select(m => new ImgReplaceItem
{
    Tag = m.Groups["tag"].Value,
    Id = m.Groups["id"].Value,
    Width = m.Groups["width"].Success ? int.Parse(m.Groups["width"].Value) : 0   
});


result:

Tag Id  Width

img 2   0
img 3   0
img 1   800


As to the code. I think it's well writen. There isn't actually much to correct if anything.

Just a small adjustment:

if (item.Contains(']'))


You could make it !item.Contains(']') and use the contintue to reduce nesting.

Code Snippets

string text = "Hi [img-2] tst[img-3] test ttteessstt grawr[img-1-800]tet";

var ids = Regex.Matches(
     text, 
     @"\[(?<tag>[a-z]+)-(?<id>\d+)(-(?<width>\d+))?\]",
     RegexOptions.IgnoreCase | RegexOptions.ExplicitCapture
)
.Cast<Match>()
.Select(m => new ImgReplaceItem
{
    Tag = m.Groups["tag"].Value,
    Id = m.Groups["id"].Value,
    Width = m.Groups["width"].Success ? int.Parse(m.Groups["width"].Value) : 0   
});
Tag Id  Width

img 2   0
img 3   0
img 1   800
if (item.Contains(']'))

Context

StackExchange Code Review Q#140669, answer score: 7

Revisions (0)

No revisions yet.