Что нового

Задачка на строки (сбалансировать строку)

AZJIO

Меценат
Меценат
Сообщения
2,892
Репутация
1,196
Suppir
Suppir сказал(а):
Как считаешь, можно ли средствами AutoIt сделать поиск-замену в тексте, который содержит вордовские таблицы.
Это уже другая тема.
 
Автор
S

Suppir

Продвинутый
Сообщения
967
Репутация
62
Я перенес в другую тему.
 
Автор
S

Suppir

Продвинутый
Сообщения
967
Репутация
62
Нашел следующие ошибки в работе:





Добавлено:
Сообщение автоматически объединено:

Текст для проверки взят здесь: http://www.kubanzdrav.ru/d20101pr978
 
Автор
S

Suppir

Продвинутый
Сообщения
967
Репутация
62
Попробуйте свой вариант функции на строке:

$line = '1. Провести 13 мая 2010 года в 11.00 в г.Краснодаре на базе государственного учреждения здравоохранения "Краевая клиническая больница N° 1 им. проф. С.В.Очаповского" департамента здравоохранения Краснодарского края (ул.1 Мая, 167, 9 блок, актовый зал) краевую научно – практическую конференцию "Хронические осложнения сахарного диабета" (далее – конференция).'

У SyDr тоже конечная точка вылезает за пределы.
 

AZJIO

Меценат
Меценат
Сообщения
2,892
Репутация
1,196
Suppir
На ещё попробуй, но это чисто подгонка под конкретный случай, ведь кто знает какой текст можно ещё придумать...
И ещё, незнаю считать ли это недостатком: если абзац-строка имеет длинну меньше указанного лимита разделения, то она не растягивается в моём примере. Может это и к лучшему.


Код:
$Buffer = Clipget()

;кусок кода из UDF File.au3 для разделения образца построчно в массив
	If StringInStr($Buffer, @LF) Then
		$aBuffer = StringSplit(StringStripCR($Buffer), @LF)
	ElseIf StringInStr($Buffer, @CR) Then ;; @LF does not exist so split on the @CR
		$aBuffer = StringSplit($Buffer, @CR)
	Else ;; unable to split the file
		If StringLen($Buffer) Then
			Dim $aBuffer[2] = [1, $Buffer]
		Else
			MsgBox(0, "Сообщение", "нет данных")
			Exit
		EndIf
	EndIf
$AllText=''
	For $i = 1 to UBound($aBuffer) - 1
		$AllText&= _Alignment($aBuffer[$i], 76, 5)&@CRLF
	Next

$AllText = StringRegExpReplace($AllText, '\n\s+\r\n',@CRLF)
ClipPut( $AllText)
MsgBox(0, "Текст весь",$AllText)

Func _Alignment($sStr, $Width=90, $redstring=5)
Local $StrTmp='', $String='', $TextOut='', $redstring0='', $aWord, $i, $x

If $redstring>0 Then
	For $i = 1 to $redstring
		$redstring0&=' '
	Next
EndIf
$aWord = StringSplit($sStr, " ", 1)

For $i = 1 to $aWord[0]
    if StringLen($String)<=$Width-$redstring+1 Then
		$StrTmp=$String
        $String &= $aWord[$i]&' '
		If $aWord[0]=$i And StringLen($String)<=$Width-$redstring+1 Then $TextOut &= $StrTmp&' '&$aWord[$i]
		If $aWord[0]=$i And StringLen($String)>$Width-$redstring+1 Then $TextOut &= $StrTmp&@CRLF&$aWord[$i]
    Else
		$StrTmp = StringTrimRight($StrTmp,1)
		For $x = 1 to 10
			If StringLen($StrTmp)<$Width-$redstring Then
				$StrTmp = StringRegExpReplace($StrTmp, '\s+', '$0 ', $Width-$redstring-StringLen($StrTmp))
			Else
				ExitLoop
			EndIf
		Next
        $TextOut &= $StrTmp&@CRLF
		$String=$aWord[$i-1]&' '&$aWord[$i]&' '
		If $aWord[0]=$i Then $TextOut &= $aWord[$i-1]&' '&$aWord[$i]
		$redstring=0
    EndIf
Next
Return $redstring0&$TextOut
EndFunc
 
Автор
S

Suppir

Продвинутый
Сообщения
967
Репутация
62
Все, сделал!

Код:
$Text = StringSplit(ClipGet(), @CRLF, 1)

For $x = 1 to $Text[0]
	ConsoleWrite(Align($Text[$x], 5, 76) & @CRLF)
Next

Func Align($line, $red, $width)
	Local $result, $redline
	if StringRegExp($line, "^\s*$") Then Return ""
	for $x = 1 to $red	
		$redline &= " "
	Next
	$line = $redline & $line & " "
	Local $mat = StringRegExp($line, "(.{1," & $width & "}) ", 3)
	for $x = 0 to Ubound($mat)-2
		while StringLen($mat[$x]) < $width
			$mat[$x] = StringRegExpReplace($mat[$x], "(\S) ", "\1  ", 10)
		WEnd

		while StringLen($mat[$x]) > $width
			$mat[$x] = StringRegExpReplace($mat[$x], "(\S)  ", "\1 ", 1)
		WEnd
		$result = $result & $mat[$x] & @CRLF
	Next
	$result = $result & $mat[Ubound($mat)-1]
	return $result
EndFunc



Теперь скрипт выдает именно тот результат, который нужен. К недостатком можно отнести не совсем равномерное наполнение пробелами, но результат выглядит вполне приемлемо.
Всем спасибо за идеи! :smile:
 

SyDr

Сидра
Сообщения
651
Репутация
158
Suppir [?]
У SyDr тоже конечная точка вылезает за пределы.
Исправил. Найди одно отличие :smile:

Код:
$sText = '1. Провести 13 мая 2010 года в 11.00 в г.Краснодаре на базе государственного учреждения здравоохранения "Краевая клиническая больница N° 1 им. проф. С.В.Очаповского" департамента здравоохранения Краснодарского края (ул.1 Мая, 167, 9 блок, актовый зал) краевую научно – практическую конференцию "Хронические осложнения сахарного диабета" (далее – конференция).'
$sText = '        ' & $sText ; здесь необходмиое число пробелов для красной строки

$sText2 = ''
$sTemp = ''

Global $nStart = 1, $nLine = 0, $nMaxLength = 76
Global $nCurrent, $nSpace, $nSpaceCurrent


While $nStart <= StringLen($sText)
    $nLine = $nMaxLength
    $nCurrent = $nStart + $nLine

    While $nLine >= $nMaxLength Or $nCurrent > StringLen($sText) Or (StringLen($sText) <> $nCurrent And StringMid($sText, $nCurrent, 1) <> ' ')
        $nCurrent -= 1
        $nLine -= 1
    WEnd

    $sTemp &= StringMid($sText, $nStart, $nLine)
    If StringLen($sText) <> $nCurrent Then
        $nSpace = $nMaxLength - $nLine
        $nSpaceCurrent = 1
    Else
        $sTemp &= StringRight($sText, 1)
    EndIf

    While $nSpace <> 0
        If StringMid($sTemp, $nSpaceCurrent, 1) = ' ' Then
            $sTemp = StringMid($sTemp, 1, $nSpaceCurrent) & ' ' & StringMid($sTemp, $nSpaceCurrent + 1)
            $nSpace -= 1
            $nSpaceCurrent += 1
        EndIf
        $nSpaceCurrent += 1
        If $nSpaceCurrent = StringLen($sTemp) Then
            $nSpaceCurrent = 1
        EndIf
    WEnd

    $sText2 &= $sTemp & @CRLF
    $sTemp = ''

    $nStart += $nLine + 1
    $nLine = 0
WEnd

ConsoleWrite($sText2)
 
Автор
S

Suppir

Продвинутый
Сообщения
967
Репутация
62
SyDr, да, точка теперь не вылезает. Но я поставил три пробела для красной строки, а в итоге получилось шесть. Т.е. лишние пробелы добавляются в красную строку.

Луше помоги в этой теме http://autoit-script.ru/index.php?topic=1832.0
У меня никак не получается делать замены внутри буфера обмена :(
 

SyDr

Сидра
Сообщения
651
Репутация
158
Suppir [?]
SyDr, да, точка теперь не вылезает. Но я поставил три пробела для красной строки, а в итоге получилось шесть. Т.е. лишние пробелы добавляются в красную строку
Угу.

Код:
$sText = '1. Провести 13 мая 2010 года в 11.00 в г.Краснодаре на базе государственного учреждения здравоохранения "Краевая клиническая больница N° 1 им. проф. С.В.Очаповского" департамента здравоохранения Краснодарского края (ул.1 Мая, 167, 9 блок, актовый зал) краевую научно – практическую конференцию "Хронические осложнения сахарного диабета" (далее – конференция).'
$sText = '  ' & $sText ; здесь необходмиое число пробелов для красной строки

$sText2 = ''
$sTemp = ''

Global $nStart = 1, $nLine = 0, $nMaxLength = 76
Global $nCurrent, $nSpace, $nSpaceCurrent


While $nStart <= StringLen($sText)
    $nLine = $nMaxLength
    $nCurrent = $nStart + $nLine

    While $nLine >= $nMaxLength Or $nCurrent > StringLen($sText) Or (StringLen($sText) <> $nCurrent And StringMid($sText, $nCurrent, 1) <> ' ')
        $nCurrent -= 1
        $nLine -= 1
    WEnd

    $sTemp &= StringMid($sText, $nStart, $nLine)
    If StringLen($sText) <> $nCurrent Then
        $nSpace = $nMaxLength - $nLine
        $nSpaceCurrent = 1
    Else
        $sTemp &= StringRight($sText, 1)
    EndIf

    While $nSpace <> 0
		If $nSpaceCurrent = 1 Then
			While StringMid($sTemp, $nSpaceCurrent, 1) = ' '
				$nSpaceCurrent += 1
			WEnd
		EndIf

        If StringMid($sTemp, $nSpaceCurrent, 1) = ' ' Then
            $sTemp = StringMid($sTemp, 1, $nSpaceCurrent) & ' ' & StringMid($sTemp, $nSpaceCurrent + 1)
            $nSpace -= 1
            $nSpaceCurrent += 1
        EndIf

        $nSpaceCurrent += 1
        If $nSpaceCurrent = StringLen($sTemp) Then
            $nSpaceCurrent = 1
        EndIf
    WEnd

    $sText2 &= $sTemp & @CRLF
    $sTemp = ''

    $nStart += $nLine + 1
    $nLine = 0
WEnd

ConsoleWrite($sText2)
 
Верх