[字号:  ]

一个超级困难的问题,做了2个月,还是没有解决。希望大家帮我。

发布时间:2008-10-26 15:53   作者: subs   信息来源: PHPChina 开源社区门户
我目前在开发一个小说的浏览功能,但是小说很长,一般在1000万字左右,小说里面还有图片,该小说的内容保存在数据库里。
在浏览小说的时候打算分页,比如浏览1000万的小说就分1000页,每页就1万字左右,但是因为小说里面有图片,导致按字数分的时候出现问题。
比如html <img src=aaaa.jpg>有可能就被截断了,<img src=a  在第一页,aaa.jpg>  在下一页,请问怎么解决这个问题,谢谢

最新回复

subs at 2008-10-26 15:53:34
能不能做成遇到html代码,等代码结束了再分页。
海底人 at 2008-10-26 16:02:39
有一个想法,不知是否可行,你可以在每页的节点处做一个缓冲区,比如向前取200个字符,向后取200个字符,这样整个缓冲区内就有400个字符,然后在这400个字符中进行判断,在没有HTML代码的地方取一个分页节点.

我现在就是用这个方法,感觉还行,不知是否适合你!!!
showphp at 2008-10-26 16:09:23
shm385 at 2008-10-26 16:37:25
判断前后50个字符都不允许有HTML的东西
action2001 at 2008-10-26 19:37:56
没试过啊,手动插入分页符吧
xyiyo at 2008-10-26 20:32:16
遇到图片时判断图片长度,按图片长度所占文字的行数来判断,LZ可以去试下~~虽然我没做过,不过应该可行的
yz20sui at 2008-10-26 21:03:31
过滤掉html再分页啊
panjinww at 2008-10-26 22:02:42

QUOTE:

原帖由 海底人 于 2008-10-26 16:02 发表
有一个想法,不知是否可行,你可以在每页的节点处做一个缓冲区,比如向前取200个字符,向后取200个字符,这样整个缓冲区内就有400个字符,然后在这400个字符中进行判断,在没有HTML代码的地方取一个分页节点.

我现在就是 ...
偶也是这么整的
subs at 2008-10-26 22:41:06
郁闷了好久,就是写不出来啊
subs at 2008-10-26 22:42:08

QUOTE:

原帖由 showphp 于 2008-10-26 16:09 发表
尝试补全标签

http://tidy.sourceforge.net/

http://tw2.php.net/tidy
补全应该怎么用了,谢谢
subs at 2008-10-26 22:46:26
应该先拆分,再补全,这样图片就会前一页和后一页都存在啊
subs at 2008-10-26 22:52:10
不过补全也算是个办法,谢谢。
不知道还有别的方案没有啊?
CrossMaya at 2008-10-26 22:55:04
其实用>当定位符也可以!

0-1000的字符搜索是否有> 如果有就多一位 截取 然后再截取 不过麻烦点
subs at 2008-10-26 23:11:19

QUOTE:

原帖由 CrossMaya 于 2008-10-26 22:55 发表
其实用>当定位符也可以!

0-1000的字符搜索是否有> 如果有就多一位 截取 然后再截取 不过麻烦点
不对,>可以是标签的开始,也可以是结束,所以不能判断。
<a href='aaa.htm'>aaa</a>
这里要是以>,就会出问题,在前面就被截断了,链接字就不见了
CrossMaya at 2008-10-26 23:13:55
我以为就图片 没考虑链接

那还是用标签补全吧 没弄过标签不全 弄完了 贴个代码看看
xiaoxiao0503 at 2008-10-26 23:17:54
晕  原文章就没个章节啥的呀
貌似比较复杂,楼主弄完了代码分享下。。。

个人觉得还是标签补全比较好些
subs at 2008-10-26 23:20:28
目前标签确实是个好办法,代码量也不多,唉,搞了很久了,是个难题
subs at 2008-10-26 23:25:11
<%
'Version        1.2
'Author                Turnip
'QQ                        63842303
'Update                2008-6-21 3:21:15

'        使用实例:
'
'        Dim strCnt
'        strCnt = "<P>0<FONT face=Verdana>1<BR>2<BR>3<BR>4</FONT><table><tr><td></td></tr></table>5</P>6"
'
'        Dim clsDoc,content,setpage
'
'        Set clsDoc = new splitDoc
'        clsDoc.sStr = str(0)                                        字符串
'        clsDoc.pageSize = 1                                                第页显示的字符数(可选,默认为1000个字符)
'        clsDoc.curPage = Request("docpage")                要显示的页码
'        content = clsDoc.getStr()                                截取后的内容
'        setpage = clsDoc.showPage(para)                        翻页
'        Set clsDoc = Nothing


Class splitDoc
    Private sRegExp         '正则对象
    Private arrLable        '存放标签的数组
    Private arrTotal        '存放数据和空标签的数组
    Private isInFst         '标签是否在字符串的开始
    Private isNeedSplit     '是否需要分隔
    Private isIncLabel      '字符串是否含有标签
    Private delimiter       '分隔符
    Public sStr             '字符串
    Public pageSize         '每页显示的字数---默认为1000字
    Public curPage          '现在要显示的页码---默认为第一页
    Private totalPage        '共有几页

    Public Function getStr()
        Call chkNeedR
        If isNeedSplit Then
            Dim iLable, iTotal, tmpNum, curNum, startNum, endNum, startPos, lenTmp, strTmp
                        Call chkCurPage()
            If Not isIncLabel Then '不含有标签,直接截取
                startPos = pageSize * (curPage - 1) + 1
                getStr = Mid(sStr, startPos, pageSize)
            Else
                curNum = 0
                startNum = pageSize * (curPage - 1) + 1
                endNum = pageSize * curPage
                iLable = 0
                Call getArrLable
                Call getArrTotal
                For iTotal = 0 To UBound(arrTotal)
                    lenTmp = Len(arrTotal(iTotal))
                    If lenTmp > 0 Then
                        If curNum < startNum Then
                            If curNum + lenTmp >= startNum Then
                                If curNum + lenTmp >= endNum Then
                                                                        strTmp = strTmp & Mid(arrTotal(iTotal), startNum - curNum, endNum - startNum + 1)
                                    strTmp = strTmp & joinArrLable(iLable)
                                    Exit For
                                Else
                                    strTmp = strTmp & Mid(arrTotal(iTotal), startNum - curNum)
                                    curNum = curNum + lenTmp
                                End If
                            Else
                                curNum = curNum + lenTmp
                            End If
                        ElseIf curNum < endNum Then
                            If curNum + lenTmp <= endNum Then
                                strTmp = strTmp & arrTotal(iTotal)
                                curNum = curNum + lenTmp
                            Else
                                strTmp = strTmp & Mid(arrTotal(iTotal), 1, endNum - curNum)
                                strTmp = strTmp & joinArrLable(iLable)
                                Exit For
                            End If
                        Else
                            strTmp = strTmp & joinArrLable(iLable)
                            Exit For
                        End If
                        strTmp = strTmp & addALable(iLable)
                    Else
                        strTmp = strTmp & addALable(iLable)
                    End If
                Next
                getStr = TrimBlank(strTmp)
            End If
        Else
            getStr = sStr
        End If
    End Function

    Private Function joinArrLable(strtIndex)
        Dim i
        For i = strtIndex To UBound(arrLable)
            joinArrLable = joinArrLable & arrLable(i)
        Next
    End Function

        Private Sub chkCurPage()
                If Not IsNumeric(curPage) Then
                        curPage=1
                ElseIf CDbl(curPage)<1 Then
                        curPage = 1
                ElseIf CDbl(curPage)>totalPage Then
                        curPage=totalPage
                End If
        End Sub

    Private Function addALable(index)
        If index <= UBound(arrLable) Then
            addALable = arrLable(index)
            index = index + 1
        End If
    End Function

    Private Sub Class_Initialize()
        Set sRegExp = New RegExp
        sRegExp.Pattern = "<[^>]*>"
        sRegExp.IgnoreCase = True
        sRegExp.Global = True
        pageSize = 1000
        curPage = 1
        delimiter = "$split"
    End Sub
   
    Private Function TrimBlank(ByVal str)
                Dim arrPattern(2),i
                arrPattern(0) = "<tr[^>]*>(<td[^>]*>\s*<\/td>)*<\/tr>"
                arrPattern(1) = "<table[^>]*><\/table>"
                arrPattern(2) = "<p[^>]*>(<\/?[^>]*>)*</p>"
                For i=0 To UBound(arrPattern)
                        sRegExp.Pattern = arrPattern(i)
                        str = sRegExp.Replace(str, "")                       
                Next
                TrimBlank = str
    End Function
   
    Private Sub Class_Terminate()
        Set sRegExp = Nothing
    End Sub

    Private Sub getArrLable()
        Dim Match, Matches, RetStr, strTmp
        strTmp = sStr
        Set Matches = sRegExp.Execute(strTmp)
        For Each Match In Matches
            RetStr = RetStr & delimiter & Match.Value
        Next
        arrLable = Split(Mid(RetStr, Len(delimiter) + 1), delimiter)
    End Sub

    Private Sub getArrTotal()
        Dim strTmp
        strTmp = sStr
        arrTotal = Split(sRegExp.Replace(strTmp, delimiter), delimiter)
    End Sub

    Private Sub chkNeedR()
                On Error Resume Next
        Dim strTmp, totalChr
        strTmp = sStr

        totalChr = Len(sRegExp.Replace(strTmp, ""))
        If Len(strTmp) <= pageSize Or totalChr <= pageSize Then
            totalPage = 1
            isNeedSplit = False
        Else
            totalPage = Fix(totalChr / pageSize)
            If (totalChr Mod pageSize) <> 0 Then totalPage = totalPage + 1
            isNeedSplit = True
        End If
        isIncLabel = sRegExp.test(strTmp)
    End Sub
   
    Public Function showPage(para)
        Dim arr,i,n
                ReDim arr(totalPage)
        For i = 1 To totalPage
            If CStr(i) = CStr(curPage) Then
                arr(n) = "<span style=""color:red;"">[" & i & "]</span> "
            Else
                arr(n) = "<a href='?docpage=" & i & para & "'>[" & i & "]</a> "
            End If
            n = n + 1
        Next
        If totalPage > 1 Then showPage = "<div class=""docpage"" style=""text-align:center;"">" & Join(arr, "") & "</div>"
    End Function
End Class
%>
subs at 2008-10-26 23:25:43
贴了段asp的,能解决这个问题,但是太复杂了,不想翻译成php
subs at 2008-10-27 09:28:50
今天写了补全,还是不行:

<a href=aaaa.jpg>sdfdsf</a>

前一页是:<a href=aa
后一页是:aa.jpg>sdfdsf</a>
结果前一页被补全成了:<a href=aa></a>
后面的aa.jpg不见了