vb.net string - эффективно заменять токены-заполнители

Я просто ищу идеи с небольшой проблемой. У меня есть строка, которая является шаблоном для сообщения, например:

Dear [[Guest.FirstName]],

We hope your are looking forward to your holiday in [[Booking.ResortName]]

Моя текущая система замены маркеров пробелов (например, [[Guest.FirstName]]) очень неэффективна, внутри циклов есть циклы, и это занимает слишком много времени.

То, что я ищу, - это способ пройти через строку, пока она не найдет [[что-то]], затем заменить это [[что-то]] на его реальное значение, а затем продолжить через строку.

Пожалуйста, обратите внимание, чтобы заменить [[что-то]], тогда мне нужно иметь доступ к держателю пробела (т.е. мне нужно знать, является ли он [[Guest.FirstName]] или [[Booking.ResortName]]).

Любые предложения по эффективному способу достижения этого были бы очень благодарны, я чувствую, что это должно быть довольно просто, но все, что я могу придумать, заканчивается циклами внутри циклов.

Спасибо!

Фил.

1 ответ

Решение

Есть много факторов, которые влияют на производительность, поэтому трудно сказать, не зная всех подробностей, какой метод будет наиболее эффективным. Тем не менее, когда дело доходит до простоты кодирования, используя RegEx MatchEvaluator будет отличным вариантом. Я уверен, вы согласитесь, что он намного чище, чем то, что вы сейчас используете:

Public Function ReplacePlaceholders(data As String) As String
    Dim r As New Regex("\[\[(?<placeholder>.*?)\]\]")
    data = r.Replace(data, New MatchEvaluator(AddressOf PlaceHolderReplacementEvaluator))
End Function

Private Function PlaceHolderReplacementEvaluator(match As Match) As String
    Dim name As String = match.Groups("placeholder").Value
    Return LookUpValueByPlaceholderName(name)   ' Replace with value lookup logic here
End Function

Если общее количество заполнителей в данных будет довольно небольшим, а список возможных заполнителей небольшим, то, вероятно, лучше всего иметь их список со своими значениями и заменить их следующим образом:

Public Function ReplacePlaceholders(data As String) As String
    Dim placeHolders As Dictionary(Of String, String) = LoadPlaceHolders()
    For Each i As KeyValuePair(Of String, String) In placeHolders
        data = data.Replace(i.Key, i.Value)
    Next
    Return data
End Function

Private Function LoadPlaceHolders() As Dictionary(Of String, String)
    Dim placeholders As New Dictionary(Of String, String)
    ' Load data here
    Return placeholders
End Function

Если вы действительно хотите найти наиболее эффективное решение, переходите от символа к символу и добавляйте по мере StringBuilder или выход Stream будет вашим лучшим вариантом. Это не будет красиво, но если вы публикуете то, что у вас есть, в CodeReview, могут быть люди, которые найдут способы сделать его немного менее уродливым:)

Другие вопросы по тегам