Страницы: 1
RSS
Выбор случайного значения из списка-массива (спинтакс)
 
Всем доброго вечера!
Не смог кратко полностью описать в заголовке вопрос, но как бы основную проблему написал. Теперь подробнее.
На днях столкнулся с новой задачей и никак не могу ее до конца решить.
Суть:
Найти в файле "html" все конструкции типа спинтакс, например, "{Доброго дня|Здравствуйте|Привет}, {уважаемый|дорогой} Петр!", случайным образом выбрать один вариант и заменить им набор. Т.е., в результате должно получиться:
- Доброго дня, уважаемыйПетр!
- Здравствуйте, дорогой Петр!
- Привет, уважаемый Петр!
- и т.д.

Возникшие вопросы:
1. Как лучше считывать данные из файла "html" в кодировке UTF-8 без BOM?
Много всего перелопатил - получилось только импортом на лист (переделал из макрорекордера):
Код
Sub loadhtml()
Dim wb As Workbook
Dim shM As Worksheet

Set wb = ActiveWorkbook
Set shM = wb.Sheets("Лист2")

sFiles = "c:\test\1.html"
With shM.QueryTables.Add(Connection:= _
    "TEXT;" & sFiles, Destination:= _
    Range("$A$1"))
    .AdjustColumnWidth = False
    .TextFilePlatform = 65001
    .Refresh BackgroundQuery:=False
End With
End Sub

Проблема этого решения, что я не знаю как искать конструкции "{||}" в случае, если начало конструкции в одной строке, а конец в другой. Плюс, мне кажеться можно как-то обработать текст не записывая на лист, и соответственно будет работать быстрее.

2. Поиск конструкции "{||}"
С учетом п.1, ищу построчно:
Код
Sub spintaks()
Dim wb As Workbook
Dim shM As Worksheet
Dim er&         'последняя строка
Dim arrTemp     'массив синонимов
Dim b&          'позиция искомого символа в строке, в нашем случае - "{"
Dim s$          'конструкция типа "{||||}"
Dim a$          'переменная для списка элементов массива
Dim poz As Integer  'позиция случайно выбранного значения
Dim wordi$          'случайно выбранное значение (синоним) из массива

Set wb = ActiveWorkbook
Set shM = wb.Sheets("Лист3")

er = shM.Cells(shM.Rows.Count, 1).End(xlUp).Row

For i = 1 To er
    b = InStr(1, shM.Cells(i, 1).value, "{")
    Do While b <> 0
        stri = shM.Cells(i, 1).value
        s = Mid(stri, InStr(1, stri, "{"), Len(stri) - InStr(1, stri, "{") - (Len(stri) - InStr(1, stri, "}") - 1))
        a = Replace(Replace(s, "}", ""), "{", "")
        arrTemp = Split(a, "|")
        Randomize
        poz = Rnd * UBound(arrTemp)
        wordi = arrTemp(poz)
        shM.Cells(i, 1).value = Replace(shM.Cells(i, 1).value, s, wordi)
        b = InStr(1, shM.Cells(i, 1).value, "{")
    Loop
Next i
End Sub

Вопросы:
-Как обрабатывать если начало конструкции в одной строке, а конец в другой (вполне может быть что даже не в следующей, а через одну или две)?
-Никак не придумаю как обрабатывать случаи, когда есть вложенные конструкции, например, "{Сегодня {отличный|хороший|прекрасный} день!|Как {дела|поживаете}}."

3. Сохранение полученного текста в формате "html" в кодировке UTF-8 без BOM.
Решил таким образом:
Код
Sub savehtm()
Dim wb As Workbook
Dim shM As Worksheet
Dim er&         'последняя строка
Dim mypath$     'путь сохранения файла

Set wb = ActiveWorkbook
Set shM = wb.Sheets("Лист3")
mypath = "c:\test\1.html"

Set FSO = CreateObject("Scripting.FileSystemObject")
Set outFile = FSO.CreateTextFile(mypath)
er = shM.Cells(shM.Rows.Count, 1).End(xlUp).Row

For i = 1 To er
    outFile.WriteLine shM.Cells(i, 1).value
Next i
outFile.Close

ss = LoadTextFromTextFile(mypath)
sss = SaveTextToFile(ss, mypath, "utf-8noBOM")
End Sub

Функции "LoadTextFromTextFile" и "SaveTextToFile" нашел где-то на просторах интернета пару лет назад - спасибо автору - часто выручают:
Скрытый текст

Т.о., повторю вопросы:
1. Как лучше считывать данные из файла "html" в кодировке UTF-8 без BOM?
2. Как обрабатывать если начало конструкции в одной строке, а конец в другой (вполне может быть что даже не в следующей, а через одну или две)?
3. Никак не придумаю как обрабатывать случаи, когда есть вложенные конструкции, например, "{Сегодня {отличный|хороший|прекрасный} день!|Как {дела|поживаете}}."
Помогите пож-та.
Вродь пока все, извините за большое количество текста..
 
NaMoRZA,
Цитата
NaMoRZA написал:
Как лучше считывать данные из файла "html" в кодировке UTF-8 без BOM?
Если вам необходимо считать данные с html файла, который располагается у вас на диске, то считать данные и записать в переменную(в нашем случае txt)
Код
    Dim FSO As Object
    Dim TS As Object
    mypath = "c:\test\1.html"
    Set FSO = CreateObject("Scripting.FileSystemObject")
    Set TS = FSO.GetFile(mypath).OpenAsTextStream(1, -2)
    txt = TS.ReadAll
    TS.Close
Цитата
NaMoRZA написал:
Как обрабатывать если начало конструкции в одной строке, а конец в другой
Ну а потом эту переменную обрабатывать регулярными выражениями, split'ами...
С вас бы файл пример, так быстрее разбор пойдет...
 
NaMoRZA, получилось корявенко, но работает :)
html закиньте в вашу папку на диске C:
 
Jungl,спасибо за помощь! Но по ходу что-то не так + с кодировкой по ходу такие же проблемы, с которыми и я сталкивался. Вот прикладываю файл - посмотрите что получается.
Изменено: NAMORZA - 17.09.2016 01:59:38
 
Jungl,вот кстати на другом форуме по поводу кодировки открываемого файла подсказали:
Код
Dim objStream, strData
Set objStream = CreateObject("ADODB.Stream")
objStream.CharSet = "utf-8"
objStream.Open
objStream.LoadFromFile("c:\test\123.html")
strData = objStream.ReadText()
Вот, поменял в Вашем макросе - теперь с кодировкой все нормально, только с выбором слов пока непонятно - я уже раз 5 пробовал разобраться с рег.выражениями все никак не получается..((
Изменено: NAMORZA - 17.09.2016 02:08:22
 
NAMORZA, используйте при чтении с файла кодировку UTF-8:(см.файл)
Код
txt = LoadTextFromTextFile(sFile, "utf-8")

Function LoadTextFromTextFile(ByVal Filename$, Optional ByVal encoding$) As String
On Error Resume Next: Dim txt$
If Trim(encoding$) = "" Then encoding$ = "utf-8"
With CreateObject("ADODB.Stream")
.Type = 2:
If Len(encoding$) Then .Charset = encoding$
.Open
.LoadFromFile Filename$
LoadTextFromTextFile = .ReadText
.Close
End With
End Function
 
Jungl,спасибо! Считываются файлы отлично!
Только выборка не происходит из списка вариантов. На сколько я понимаю, Вы каким-то образом учитываете наличие тегов, типа "<p>" - это не совсем то, потому что конструкции могут быть где угодно, например, может быть такое
Код
"<div style="text-align:{center|left|right};"><a style="font-size:{14|13|12|10|9}px;color:{blue|grey|#29292b};" href="{mysite.ru|my1site.ru|sites{1|2|3|4|5}.ru}">{Посмотреть погоду|А гляньте ка сюда|Смотрите что у нас|Здесь отлично}</a></div>"
или
Код
"<title>{Какие мы {классные|хорошие}|Заходите к нам на огонек}!</title>"
.
Как то так. Плюс, мы должны больше ничего не трогать и на выходе должна получиться html-страница только уже с конкретными случайными значениями.
Прикрепил оригинал и вариант конечного файла.
Изменено: NAMORZA - 17.09.2016 09:39:27
 
Цитата
NAMORZA написал: на другом форуме... подсказали
Цитата
Публикуя один и тот же вопрос в разных форумах и на дружественных сайтах вы заставляете сразу нескольких людей параллельно думать над вашей задачей и обесцениваете усилия тех, кто даст ответ вторым-третьим и т.д.
Чтобы не расходовать чужое время впустую, нужно самостоятельно указывать ссылки на параллельные обсуждения
 
Параллельное обсуждение - http://www.cyberforum.ru/vba/thread1808717.html
Я редко что-то спрашиваю на форумах - всегда стараюсь сам разбираться. Но мой опыт показывает, что обсуждая тему в 2-х форумах - обычно получаются как минимум разные подходы в решении + если находится какое-то решение на одном форуме - я всегда тут же его показываю на втором как раз для того чтобы те люди, которые помогают решить вопрос не тратили свое время зря.
Мне кажется, в этом ничего плохого нет, а только плюсы для всех.
Сам иногда кому-то помогаю если знаю решение, но обычно, к сожалению, просто физически не хватает времени.. - 2 ненормированных работы максимально забирают время, а когда-то еще и семье и детям надо уделять внимание..
Изменено: NAMORZA - 17.09.2016 12:29:52
 
NAMORZA, судя по всему, здесь нужно писать скрипт, который будет выделять каждую строку из переменой и ее обрабатывать. Логика примерно такая:
имеем текст с разделителями >...<, <br>, <title>, Chr(10), etc
Скрытый текст

считываем первую строку, далее можно рандомно выбирать 1 кусок текста из шаблонов {...} используя внутри разделитель "|", например:
1. Из первого шаблона рандомно стянули "Здравствуйте"
2. берем символы между шаблонами }...{ в данном случае это запятая с пробелом
3. Из второго шаблона рандомно стянули "уважаемый"
4. Если после шаблонов до разделителя есть какой нибудь слово, значит оно играет роль основы, в данном случае Петр!(между шаблонами и Петром есть пробел :))
5. Склеиваем: "Здравствуйте" + ", " + "уважаемый" + " " + "Петр!"

Переходим на вторую строчку и пережевываем снова...

Надеюсь объяснил понятным языком? :)
Страницы: 1
Наверх