| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 5265 人关注过本帖
标题:求从字符串取指定字符前的数字部分,数字长度不一
只看楼主 加入收藏
sdta
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
来 自:江苏省连云港市
等 级:版主
威 望:335
帖 子:9841
专家分:27213
注 册:2012-2-5
收藏
得分:0 
本回帖只是根据楼主的问题写的代码,没有普遍性。
CLEAR
TEXT TO cStr NOSHOW
NO.04833357-04833358已认证进项
NO.04833357~04833358已认证进项
NO.04833357:04833358已认证进项
NO.04833357:04833358已认证进项
NO.04833357,-04833358已认证进项
NO.04833357,04833358已认证进项
NO.04833357、04833358已认证进项
NO.04833357.04833358已认证进项
NO.04833357。04833358已认证进项
NO.04833357&04833358已认证进项
#04833357,04833358进项发票
NO.04833357任何汉字或字母或空格04833358已认证进项
NO.04833357-366已认证进项(366-357小于50张时)
NO.04833357,366已认证进项
ENDTEXT
=ALINES(ArrayName,cStr)
FOR i = 1 TO ALEN(ArrayName)
    c2 = ""
    n1 = 0
    FOR ii = 1 TO LENC(ArrayName[i])
        c1 = SUBSTRC(ArrayName[i],ii,1)
        IF INLIST(c1,"已","进")
            EXIT
        ENDIF
        IF ISDIGIT(c1)
            c2 = c2 + c1
        ENDIF
    ENDFOR
    c3 = SUBSTR(c2,9)
    c2 = LEFT(c2,8)
    ?c2 + "-" + LEFT(c2,8 - LEN(c3)) + c3
ENDFOR

坚守VFP最后的阵地
2018-09-20 21:07
csyx
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
来 自:火星
等 级:版主
威 望:37
帖 子:708
专家分:2848
注 册:2018-3-13
收藏
得分:3 
能确定规则就应该能拆分清楚
程序代码:
Text to cTest Noshow pretext 1+2
    NO.04833357-04833358已认证进项
    NO.04833357~04833358已认证进项
    NO.04833357:04833358已认证进项
    NO.04833357:04833358已认证进项
    NO.04833357,-04833358已认证进项
    NO.04833357,04833358已认证进项
    NO.04833357、04833358已认证进项
    NO.04833357.04833358已认证进项
    NO.04833357。04833358已认证进项
    NO.04833357&04833358已认证进项
    #04833357,04833358进项发票
    NO.04833357任何汉字或字母或空格04833358已认证进项
    NO.04833357-366已认证进项(366-357小于50张时)
    NO.04833357,366已认证进项
EndText
Create Cursor test (f1 V(50), f2 V(50), no1 V(8), sep C(1), no2 V(8))
For i = 1 to ALines(aTest, cTest, 5)
    Insert into test (f1) Values (aTest[i])
EndFor

*-- 规则: [-] [~] [:] 表示连号符
cHyp = '-~:'
Replace all f2 with Strconv(f1, 2)
Replace all f2 with Chrtran(f2, Chrtran(f2, '1234567890'+cHyp, ''), ;
                    Replicate(',', Len(Chrtran(f2, '1234567890'+cHyp, ''))))
Scan all
    cf2 = f2
    For i = 1 to Len(cHyp)
        c = Substr(cHyp,i,1)
        cf2 = Strtran(cf2, c, ','+c+',')
    EndFor
    i = ALines(aTest, cf2, 5, ',')
    Do case
    Case i > 2
        Replace next 1 no1 with aTest[1], sep with Iif(aTest[2]<>',','-',','), no2 with aTest[3]
    Case i > 1
        Replace next 1 no1 with aTest[1], sep with ',', no2 with aTest[2]
    Case i > 0
        Replace next 1 no1 with aTest[1]
    Otherwise
    EndCase
EndScan
Replace all no2 with Left(no1, Len(no1)-Len(no2)) + no2 for Len(no2) < Len(no1)
Select f1, no1+sep+no2 as f2 from test into cursor test
Browse


[此贴子已经被作者于2018-9-20 21:16编辑过]


这家伙很懒,啥也没留下
2018-09-20 21:10
吹水佬
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:451
帖 子:10607
专家分:43186
注 册:2014-5-20
收藏
得分:0 
TEXT TO s noshow
NO.04833357-04833358已认证进项
NO.04833357~04833358已认证进项
NO.04833357:04833358已认证进项
NO.04833357:04833358已认证进项
NO.04833357,-04833358已认证进项
NO.04833357,04833358已认证进项
NO.04833357、04833358已认证进项
NO.04833357.04833358已认证进项
NO.04833357。04833358已认证进项
NO.04833357&04833358已认证进项
#04833357,04833358进项发票
NO.04833357任何汉字或字母或空格04833358已认证进项
NO.04833357-366已认证进项(366-357小于50张时)
NO.04833357,366已认证进项
ENDTEXT
FOR i=1 TO ALINES(arr,s)
    j = 1
    DO WHILE !ISDIGIT(SUBSTR(arr[i],j,1))
        j = j+1
    ENDDO
    n = j
    DO WHILE ISDIGIT(SUBSTR(arr[i],j,1))
        j = j+1
    ENDDO
    len1 = j-n
    str1 = SUBSTR(arr[i], n, len1)
    DO WHILE !ISDIGIT(SUBSTR(arr[i],j,1))
        j = j+1
    ENDDO
    n = j
    DO WHILE ISDIGIT(SUBSTR(arr[i],j,1))
        j = j+1
    ENDDO
    len2 = j-n
    str2 = SUBSTR(arr[i], n, len2)
    IF len1 > len2
        str2 = LEFT(str1, len1-len2) + str2
    ENDIF
    ? str1, str2
ENDFOR
2018-09-20 22:07
厨师王德榜
Rank: 18Rank: 18Rank: 18Rank: 18Rank: 18
等 级:贵宾
威 望:199
帖 子:991
专家分:4966
注 册:2013-2-16
收藏
得分:3 
说一下我的思路,我以三个Func()来处理任何字串。
以字串“NO.04833357,-04833358已认证进项”为例
FuncA():本模块目的,把任何传入的字串,分解为两个数字字串。
本模块思路(这里只给思路,代码没时间写)
先找到字串的第一个数字位置:4
再逐字符向右推,找到第一个分隔符(也就是非数字 字符)位置:在本例中,这个位置是12
从而倒推出第一段数字 ,是从位置4 到位置 11
由于分隔符有时不只一个,比如本例中,-都是分隔符,所以从位置12起,需要逐字符向右推,
再找下一个首数字位置,本例是:14
再找最后一个数字位置,本例是:21
由此,取出两段数字字串,
位置 4-11 (04833357)和 位置 14-21 (04833358)

以上为阶段A。根据以上思路,做一个FuncA(“NO.04833357,-04833358已认证进项”)
返回两个值。04833357 和 04833358

阶段B:比较两个字串的长度是否相等,如相等,则跳过本Func ,直接 把两个字串输入阶段C
如不相等……
FuncB(字串1,字串2)
如不相等,例如:“NO.04833357,366已认证进项”经过FuncA后,得到的是两个长度不等的字串:
04833357 和 366,那么此时FuncB就有用武之地了,本FuncB()发现两个字串不等时,
以较长字串的左边开始,与较短字串对齐,例如 04833357 和 366 ,
经过本FuncB处理后,输出的是两个长度相等的字串:04833357 和 04833366
得到两个相等字串后,再把他输入到FuncC“阶段C”

阶段C:(确定用哪个分隔符,最后输出整理好的字串)
由于FuncA已经找到了分隔符的起始位置,“NO.04833357,-04833358已认证进项”为例
找到的分隔符起始位置是:12,13,从而可以取得原分隔符“,-”
再按以下规则,替换成转换后的分隔符:

从描述来看,基本是如下规则:
当原来的分隔符是一个的时候,“-” “,” 保留,其余字符(~ : 替换为 -)(、& 全角, 替换为 ,)
当原来分隔符是多个的时候,比如“NO.04833357,-04833358已认证进项”,分隔符是 ,- 两个,则替换为-
当分隔符是汉字或空格的时候,替换为 ,
……
有了以上规则,则可以把输入的参数,转换为想要的格式(字串1 + 转换后的分隔符 + 字串2)。

不过,这个分隔符复杂的转换规则,我们并不提倡,完全可以在这里统一规定:
所有分隔符一律统一为“-”,不理解你自己把自己搞那么复杂干嘛?
既然这个数据交给你来清洗,清洗规则就应该由你说了算,干嘛给自己平白增加那么多限制?

有了以上思路,你的数据可以清洗成你想要的格式。
感觉你只是缺少思路,思路帮你理清后,代码你自己肯定可以完成的。
2018-09-21 09:54
厨师王德榜
Rank: 18Rank: 18Rank: 18Rank: 18Rank: 18
等 级:贵宾
威 望:199
帖 子:991
专家分:4966
注 册:2013-2-16
收藏
得分:0 
至于判断一个字符是否数字?可以用isdig(字符),或者 ASC(字符)>=48 and   ASC(字符)<=57 来判定。
2018-09-21 09:58
pjtyzyq
Rank: 4
等 级:业余侠客
威 望:6
帖 子:232
专家分:240
注 册:2016-2-14
收藏
得分:0 
**处理一行数据
cStr = "NO.04833357,359,3361,366,04833370-90,93已认证进项"    &&不能出现“NO.04833357,359,3361以及3366”情况,即分隔符不能出现两个及以上连续全角字符
b=""
Dimension ar (10,2)    &&10:一行可能有发票号的数量
j=1
For i = 1 To Len(cStr)
    If Isdigit(Substr(cStr,i,1))=.T.
        b=b+Substr(cStr,i,1)
    Else
        If Len(b)>0
            ar(j,1)=b
            If Isdigit(Substr(cStr,i+1,1))=.F. And Isdigit(Substr(cStr,i+2,1))=.T.
                ar(j,2)=Substr(cStr,i,2)
            Else
                ar(j,2)=Substr(cStr,i,1)
            Endif
            b=""
            j=j+1
        Endif
    Endif
Endfor
c=ar(1,1)
d=ar(1,1)
For i=2 To j-1
    IF LEN(ALLTRIM(ar(i,1)))=8     && 8:发票号长度
    c=c+ar(i-1,2)+ar(i,1)
    d=ar(i,1)
    ELSE
    len_1=LEN(ALLTRIM(ar(i,1)))
    c=c+ar(i-1,2)+SUBSTR(d,1,8-LEN_1)+ar(i,1)
    d=SUBSTR(d,1,8-LEN_1)+ar(i,1)
    endif
Endfor
?c

结果:04833357,04833359,04833361,04833366,04833370-04833390,04833393

[此贴子已经被作者于2018-9-21 11:43编辑过]

2018-09-21 10:16
hgfeng1984
Rank: 7Rank: 7Rank: 7
等 级:黑侠
威 望:5
帖 子:139
专家分:513
注 册:2006-3-26
收藏
得分:3 
2018-09-22 14:21
快速回复:求从字符串取指定字符前的数字部分,数字长度不一
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.033380 second(s), 10 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved