| Eng.Home |
| Tools |
| Programming |
| Doodle (Jpn) |
| Graphics |
| Misc |
| Gate |
| About Me |
| What's New |
| Links (Jpn) |
If you want to manage something (text, csv-file, etc.) using SED, or some kind of probrem about programming, please e-mail me.
I might give you any ideas for solution. maybe....
Check Tools page, if you want to see any other samples.
I wrote these scripts or program codes with no harm, but I will not take on responsibility for their acts or for results (damage, losses etc.) by their acts or by using script/program. And I will not take on responsibility, too, for results by only having their copy without activating them.
When you use s command with g option like "s/pattern/replacement/g" to replace matched pattern repeatedly, s command sometimes lose pattern. It happens when pattern include a string that can be replaced with replacement. Because sed ignore a string that once replaced while s command is running (maybe it is to avoid occuring endless looping). So, you have to command again like following sample after a suceeded replacement.
:LOOP
s/\("[^",][^",]*\),\([^"]*"\)/\1;\2/
t LOOP
s/\(,"[^",]*","\),/\1;/g
s/\(,[^",]*,"\),/\1;/g
s/^",/";/
s/\([0-9]\)\([0-9][0-9][0-9]\)$/\1,\2/
:LOOP
s/\([0-9]\)\([0-9][0-9][0-9]\)\([^0-9]\)/\1,\2\3/
t LOOP
If you want to make variable nesting loop, try this way. You can make deep dyanamic nesting loops, such as thousand loops!, without writing many loops, without a lot of trouble. Sample is written in pascal.
program VariableNestingLoop (input, output);
var loopbegin, loopend : integer;
var ns : array [1..MAXNESTING] of integer;
begin
for i:=1 to nesting do ns[i] := loopbegin;
repeat
{ ... some looping processes or
procedure-/function-calls are here ... }
i := nesting;
ns[i] := ns[i] + 1;
while ( ns[i] > loopend ) and ( i > 0 ) do begin
ns[i] := loopbegin;
i := i - 1;
if i > 0 then
ns[i] := ns[i] +1
end
until i = 0
end.
This function is to transfer integer (from 1 to 702) to two digit alphabetical number (from "A" to "ZZ"); just like column index of Spreadsheet (e.g. MS-Excel/Lotus 1-2-3) such as series of A,B,C,...,Z,AA,AB,...,ZZ. At first sight, output "number" looks as 27 radix, but it isn't. Because this output string is "AA" for 27 instead of "A_". So this two digit alphabetical number expresses 702 at the most instead of 728 by 27 radix.
Following sample is written in Visual Basic for Application of MS-Excel. And JavaScript version of this function is below.
' Function for integer(1-702) to two digit alphabetical "number"
' written by Seiji Fujita
' Output alphabetical numbers are A,B,C...,Z,AA,AB,...,ZZ.
' Notice: output is not 27 radix.
Function Num2Alpha(num As Integer) As String
Dim upper As Integer
Dim lower As Integer
Const strRef = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
If (num <= 0) Or (num > 702) Then
Num2Alpha = "ERR"
Exit Function
End If
upper = (num - 1) \ 26
lower = (num - 1) Mod 26 + 1
If upper > 0 Then
Num2Alpha = Mid(strRef, upper, 1) + Mid(strRef, lower, 1)
Else
Num2Alpha = Mid(strRef, lower, 1)
End If
End Function
This is almost the same as (1) except output string has not "I" and "O". This rule may use in product numbering to avoid confusion 1 with I, or 0 with O. Output alphabetical number are A,B,...,H,J,...,N,P,...,Z,AA,AB,...,AH,AJ,...,AN,AP,...AZ,...,HZ,JA,...,NZ,PA,...PZ,...,ZZ. Output is not 25 radix.
' Function for integer(1-600) to two digit alphabetical "number"
' written by Seiji Fujita
' Output alphabetical numbers are A,B,...,H,J,...,N,P,...,Z,
' AA,AB,...,AH,AJ,...,AN,AP,...AZ,...,HZ,JA,...,NZ,PA,...PZ,...,ZZ.
' Notice: output is not 25 radix.
Function Num2Alpha2(num As Integer) As String
Dim upper As Integer
Dim lower As Integer
Const strRef = "ABCDEFGHJKLMNPQRSTUVWXYZ"
If (num <= 0) Or (num > 600) Then
Num2Alpha = "ERR"
Exit Function
End If
upper = (num - 1) \ 24
lower = (num - 1) Mod 24 + 1
If upper > 0 Then
Num2Alpha = Mid(strRef, upper, 1) + Mid(strRef, lower, 1)
Else
Num2Alpha = Mid(strRef, lower, 1)
End If
End Function
This function can be used on VBA for Excel 97 (Of course this can be used on VBA for Excel 2003, or Word etc., too) as substitute for Split function on VBA for Excel 2000 or later version. strSplit() requires string argument src as a source, and a numeral argument pos as an index of output string and a string argument sep as a separator (delimiter). And it returns separated string that index is sep. sep is available from 0 to N-1 when src is separeted to N strings in amount. When string sep is not found in string src or when number pos is above amount of separated words, return value becomes "" (means "null").
Please read usage for that of JavaScript version "1. (1) function for splitting strings", too.
If you want to split string contains series of spaces by space, try to use xtrim function.
' substitute of Split for after VBA 2000
' pos is a number for pick up item, first number is zero (=0)
' return value is ""(=null) when pos is over separable number
' or when src does not contain sep.
' written by Seiji Fujita
' revised for sep is null(="")
Function strSplit(ByVal src As String, ByVal sep As String, ByVal pos As Long) As String
Dim prePtr As Long
Dim postPtr As Long
Dim strWord As String
Dim i As Long
Dim flag As Boolean
If sep <> "" Then
i = 0
flag = False
Do While prePtr <= Len(src) And i <= pos
If prePtr <= 0 Then
postPtr = InStr(src, sep)
prePtr = 1
Else
postPtr = InStr(prePtr, src, sep)
End If
If postPtr >= 1 Then
strWord = Mid(src, prePtr, postPtr - prePtr)
prePtr = postPtr + Len(sep)
Else
If i > 0 And flag = False Then
strWord = Mid(src, prePtr)
Else
strWord = ""
End If
flag = True
End If
i = i + 1
Loop
If i <= pos Then
strWord = ""
End If
strSplit = strWord
Else
strSplit = ""
End If
End Function
This function can be used on VBA for Excel 97 (Of course this can be used on VBA for Excel 2003, or Word etc., too) as substitute for Split function on VBA for Excel 2000 or later version.
This function returns amount of separated words (from 0). Return value equal 0 (zero) means that string sep is not found in string src, and the value of SplitWord(0)..SplitWord(NUM-1) becomes "null". Return value equal -1 means that number of maximum value is not enough for amount of separable words (separable number > NUM + 1), and the value of SplitWord(0)..SplitWord(NUM-1) signs right separated strings, but you cannot get strings that should be separated originally as SplitWord(NUM) or SplitWord(NUM+x)...
Please read usage for that of JavaScript version "1. (2) function for splitting strings; using array", too.
If you want strSplitG() to return SplitWord[0] as src when return value of strSplitG() = 0 (that means sep is not found in src), you should set true into notfound.
' substitute of Split for after VBA 2000 ; using array
' pos is a number for pick up item, first number is zero (=0)
' return value is ""(=null) when pos is over separable number
' or when src does not contain sep.
' written by Seiji Fujita
' revised for sep is null(="")
'
' If you want to be returned SplitWord(0)=src when return value strSplitG=0
' (= when src does not contain sep), set optional parameter notfound = true.
' If notfound = false or not used notfound at that sistuation, returned SplitWord(0)="".
'
' Return value strSplitG is separable number of src (more than 0).
' When return value strSplitG = 0 that means src does not contain sep,
' and values of SplitWord(0)...SplitWord(NUM-1) = "".
' when optional parameter notfound = False or default (not set notfound).
'
' If you want to be SplitWord(0) = src, when return value strSplitG = 0
' (that means src does not contain sep), set optional parameter notfound = True.
'
' When return value strSplitG = -1 that means NUM is too small for separable
' number of src (separable number > NUM + 1), at that time values of
' SplitWord(0)...SplitWord(NUM-1) is appropriate string, but you cannot get
' separated string on and after SplitWord(NUM).
'
' Decrare NUM as global constant (Public Const).
' Decrare array for SplitWord() in parent procedure/function.
Function strSplitG(ByVal src As String, ByVal sep As String, _
ByRef SplitWord() As String, Optional notfound As Boolean) As Integer
Dim prePtr As Long
Dim postPtr As Long
Dim strWord As String
Dim i As Long
Dim flag As Boolean
Erase SplitWord
If sep <> "" Then
i = 0
flag = False
Do While prePtr <= Len(src) And flag = False And i <= NUM
If prePtr <= 0 Then
postPtr = InStr(src, sep)
prePtr = 1
Else
postPtr = InStr(prePtr, src, sep)
End If
If postPtr >= 1 Then
SplitWord(i) = Mid(src, prePtr, postPtr - prePtr)
prePtr = postPtr + Len(sep)
Else
If i > 0 And flag = False Then
SplitWord(i) = Mid(src, prePtr)
prePtr = Len(src) + 1
End If
flag = True
End If
i = i + 1
Loop
If InStr(prePtr, src, sep) > 0 And i > NUM Then '----(A)
strSplitG = -1
Else
If i = 1 Then ' And SplitWord(0) = ""
strSplitG = 0
If notfound = True Then
SplitWord(0) = src
End If
Else
strSplitG = i
End If
End If
Else
strSplitG = 0
If notfound = True Then
SplitWord(0) = src
End If
End If
End Function
** You can write If-statement on line (A) as follows (same logic).
If Len(Mid(src, prePtr)) > 0 And i > NUM Then
* Usage Sample
Public Const NUM As Integer = 20
Sub Sample()
Dim SplitWord(NUM) As String
Dim i As Integer
Dim str As String
MsgBox "Number of separation is: " & strSplitG("abcdefg", "c", SplitWord())
str = "Result of separation: "
For i = 0 To NUM
str = str & CStr(i) & "=" & SplitWord(i) & " / "
Next i
MsgBox str
End Sub
* If you want Split function for Excel 97 VBA just like that for Excel 2000 VBA, Check web-page
SPLIT-funktion for Excel 97
You can calculate age with DATEDIF of Excel worksheet function (* note), but you can not get same answer with similar function datediff of VBA in same manner (refer to [2004-06-24] Bug of MS Excel 97 function).
* [added on 2023-02-12] DATEDIF of Excel worksheet function also turned out to be wrong about leap years. It returns wrong age (1 less value) for February 28th in a normal year born on February 29th in a leap year (Confirmed with Excel 97, Excel 2003, Excel 2010, Office 365 Excel Online).
An extream examle to calculate age at January 1, 2007 for birthday December 31, 2006 using Datediff("yyyy","2006/12/31", "2007/01/01"), result is 1 instead of 0. This is a "specification" of VBA (I don't agree it, and I think it is a bug!). So it is necessary to manage to get right answer. (This strange spec took over from Excel 97 (maybe Excel 95 too) to Excel 2003.)
To get right age with CalcAge() in integer requires string argument daybirth as birthday in format yyyy/mm/dd (mm and/or dd can be 1-digit) and string argument fixday as date to fix age in format yyyy/mm/dd (mm and/or dd can be 1-digit). daybirth and fixday is needed in 1 byte code string. But this function retouch it into 1 byte code if they contain 2 byte code to avoid error. When calling from VBA, fixday can be given a date using the Date() function, Now() function, CDate() function, etc. (because they are automatically converted to strings).
When using this function like "=CalcAge(A1,B1)" on the worksheet, the date-related functions are not automatically converted to strings, so it is necessary to convert them like this: TEXT(NOW(),"YYYY/MM/DD") or TEXT(TODAY(),"YYYY/MM/DD"). The format can be "YYYY/M/D".; e.g.: write =CalcAge("2000/1/3",TEXT(TODAY(),"YYYY/MM/DD")) instead of =CalcAge("2000/1/3",TODAY()). Note that no special format specification is required when specifying a cell in which a date-related function has been assigned.; e.g.: You can write =CalcAge("2000/1/3",D10) when =TODAY() is assigned to cell D10.
--> This problem can be solved by declaring the type of daybirth and fixday as Date instead of String.
For function IsLeapYear(), refer to the function described in Function to check whether the specified day is a holiday.
' This function calculate right age at appointment day in VBA
' daybirth, fixday are string in format yyyy/mm/dd (mm and/or dd can be 1-digit)
' return value
' if in normal: 0 or positive integer
' if in abnormal: negative integer
' daybirth or/and fixday are not in right format : -1
' daybirth > fixday : -2
' Message Box shows when mgflag = True and return value < 0,
' written by Seiji Fujita
' revised by Seiji Fujita on February 12, 2023
' revised by Seiji Fujita on October 15, 2024
Function CalcAge(ByVal daybirth As Date, ByVal fixday As Date, _
Optional ByVal msgflag As Boolean) As Integer
Dim bmd As Integer
Dim fmd As Integer
' convert parameter into 1 byte code if they contain 2 byte code
daybirth = StrConv(daybirth, vbNarrow)
fixday = StrConv(fixday, vbNarrow)
If (IsDate(daybirth) And IsDate(fixday)) = False Then
If msgflag = True Then
MsgBox "parameter(s) is/are not in right format", vbCritical
End If
CalcAge = -1
Exit Function
End If
If daybirth > fixday Then
If msgflag = True Then
MsgBox "fixday is older than daybirth", vbCritical
End If
CalcAge = -2
Exit Function
End If
bmd = 100 * Month(daybirth) + Day(daybirth)
fmd = 100 * Month(fixday) + Day(fixday)
CalcAge = DateDiff("yyyy", daybirth, fixday)
If CalcAge > 0 And fmd < bmd Then
If IsLeapYear(Year(daybirth)) And bmd = 229 Then
If Not (Not (IsLeapYear(Year(fixday))) And fmd = 228) Then
CalcAge = CalcAge - 1
End If
Else
CalcAge = CalcAge - 1
End If
End If
End Function
Sub Sample()
MsgBox CalcAge("2006/12/31", "2007/01/01") ' result = 0
MsgBox CalcAge("2006/12/31", CDate("February 2, 2017")) ' result = 10
MsgBox CalcAge("2006/12/31", CDate("2008-10-10")) ' result = 1
MsgBox CalcAge("1964/2/29", CDate("2007-02-28")) ' result = 43
MsgBox CalcAge("1964/2/29", CDate("2008-02-28")) ' result = 43
MsgBox CalcAge("1964/2/29", CDate("2008-02-29")) ' result = 44
MsgBox CalcAge("1980/10/10", "2005/06/02") ' result = 24
MsgBox CalcAge("1980/10/10", Now())
MsgBox CalcAge("1980/10/10", Date)
End Sub
* When using this function on the worksheet, TODAY() and NOW() must be given after converting the format as follows. =CalcAge("1980/10/10", TEXT(NOW(),"YYYY/MM/DD")) =CalcAge(A1, TEXT(TODAY(),"YYYY/M/D"))--> This problem can be solved by declaring the type of daybirth and fixday as Date instead of String.
* If you want to solve this without DateDiff function, code is like below here CalcAge2. Usage is same treatment as CalcAge.
' This function calculate right age at appointment day in VBA
' daybirth, fixday are string in format yyyy/mm/dd (mm and/or dd can be 1-digit)
' return value
' if in normal: 0 or positive integer
' if in abnormal: negative integer
' daybirth or/and fixday are not in right format : -1
' daybirth > fixday : -2
' Message Box shows when mgflag = True and return value < 0,
' written by Seiji Fujita
' revised by Seiji Fujita on February 12, 2023
' revised by Seiji Fujita on October 15, 2024
Function CalcAge2(ByVal daybirth As Date, ByVal fixday As Date, _
Optional ByVal msgflag As Boolean) As Integer
Dim bmd As Long
Dim fmd As Long
Dim bymd As Long
Dim fymd As Long
' convert parameter into 1 byte code if they contain 2 byte code
daybirth = StrConv(daybirth, vbNarrow)
fixday = StrConv(fixday, vbNarrow)
If (IsDate(daybirth) And IsDate(fixday)) = False Then
If msgflag = True Then
MsgBox "parameter(s) is/are not in right format", vbCritical
End If
CalcAge2 = -1
Exit Function
End If
bmd = 100 * Month(daybirth) + Day(daybirth)
fmd = 100 * Month(fixday) + Day(fixday)
bymd = 10000 * Year(daybirth) + bmd
fymd = 10000 * Year(fixday) + fmd
If IsLeapYear(Year(daybirth)) And bmd = 229 Then
If Not (IsLeapYear(Year(fixday))) And fmd = 228 Then
bymd = bymd - 1
End If
End If
CalcAge2 = Int((fymd - bymd) / 10000)
If CalcAge2 < 0 Then
If msgflag = True Then
MsgBox "fixday is older than daybirth", vbCritical
End If
CalcAge2 = -2
End If
End Function
* It would be easier if you use the worksheet function DATEDIF of MS Excel, but unfortunately it returns wrong age (1 less value) for February 28th in a normal year born on February 29th in a leap year. This function will not work properly.
Note:Some websites suggest that you can fix the DATEDIF bug by adding +1 the end date, but that's pointless as you'd actually make a much more disastrous mistake. Without correction, the function would be wrong only once every 4 years for those born on February 29th. With adding +1 correction, the function would be wrong once every year for 365 days excluding February 29th. Example: Born on January 25, 1999, the correct age as of January 24, 2005 is 5 years old, but the result after adjusting by +1 is 6 years old).
' Function using Excel worksheet function; An error occurs in the calculation of leap years!
Function CalcAgeWithDatedif(ByVal daybirth As String, ByVal fixday As String) As Integer
Dim strdf As String
strdf = "DATEDIF(" & """" & bd & """" & "" & "," & """" & fd & """" & "," & """Y""" & ")"
CalcAgeWithDatedif = Application.Evaluate(strdf)
End Function
For the above function, the command below should returns 3, but unfortunately it returns an incorrect 2.
MsgBox CalcAgeWithDatedif("1964/2/29", "1967/2/28") ' returns 2 instead of 3
(1) Please read usage for that of JavaScript version "5. (4) function for splitting strings" following. Note: You don't prepare trim/ltrim/rtrim function, because VBA has same functions.
Example usage: Split(xtrim(srcstring)," ") to split words from string contains one or more series of spaces.
' Function to remove spaces at the both side of string and to shrink series of spaces within string
' written by Seiji Fujita
Function xtrim(ByVal s As String) As String
Dim p As Integer
Dim tmp As String
s = Trim(s)
p = 1
Do While p < Len(s)
If Mid(s, p, 1) = " " Then
s = Left(s, p - 1) & " " & Trim(Mid(s, p + 1))
End If
p = p + 1
Loop
xtrim = s
End Function
If you manage 2byte spaces in string, check xtrim for 2byte code.
(2) You can write more easy way as following, but it works only with Excel.
Note: This function does not work with VBA of Word or that of Access etc.
' Function to remove spaces at the both side of string and to shrink series of spaces within string
' using worksheet's function 'trim'
' Note: this works only with Excel
Function xtrim(ByVal s As String) As String
Application.Trim(s)
End Function
#6 and #7 are omitted, because they are related to Japanese culture and written in Japanese, and probably unnecessary for English-speaking people.
This function needs Replace function in VBA of Excel 2000 or later (therefore this function doesn't work with VBA of Excel 97)
Note1: If some use trouble when replace NewLine to Null string, rewrite third parameter of Replace function from "" to " ".
Note 2: If you want to use this function in Excel 97, use/define strReplace, and replace Replace in following code into strReplace.
' Function to delete NewLine Characters(=vbLf/vbCR/vbCRLF)
' and to trim spaces on edge of string,
' and to shrink series of spaces within string.
' xtrim is a function that is opened in this page.
Function DeleteCRAndTrimSPC(ByVal str As String) As String
str = Replace(str, vbLf, "")
str = Replace(str, vbCr, "")
str = Replace(str, vbCrLf, "")
DeleteCRAndTrimSPC = xtrim(str)
End Function
This is a simple application of section 8. (1). You need select range (=worksheet cells) manually or automatically before call this function. If you need strictness, (a) you should activate applicable workbook or worksheet before call this procedure, or (b) you should rewrite "In Selection" in this function into "In ActiveSheet.Selection" or "In ActiveWorkbook.ActiveSheet" etc. not to this procedure touch unsuitable range.
Note: Actually, NewLine in Cell is vbLF only.
' Procedure to delete NewLine Characters(=vbLf/vbCR/vbCRLF)
' and to trim spaces on edge of string,
' and to shrink series of spaces within string.
' You should select range before call this function.
Sub DeleteCRAndTrimSPCInSelection()
Dim rng As Range
For Each rng In Selection
rng.Value = DeleteCRAndTrimSPC(rng.Value)
Next rng
End Sub
* For practical use, you should limit range in selection to process efficintly, using intersect(), just like followings.
Intersect(Selection, Cells.SpecialCells(xlCellTypeConstants, xlTextValues))
Note: You have to write error trap when result of intersection is nothing.
This function can be used on VBA for Excel 97 (Of course this can be used on VBA for Excel 2003, or Word etc., too) as substitute for Replace function on VBA for Excel 2000 or later version.
This function replaces string src in str by string dst.
When dst is empty (= ""), this function work as delete src in str.
' Substitute function for Replace function introduced into Excel 2000 (for Excel 97)
Function strReplace(ByVal str As String, _
ByVal src As String, ByVal dst As String) As String
Dim lStr As Integer, lSrc As Integer
Dim sLeft As String, sRight As String
Dim ptr As Integer
lStr = Len(str)
lSrc = Len(src)
sRight = str
ptr = InStr(str, src)
If lStr > 0 And lSrc > 0 And ptr > 0 Then
Do While ptr > 0
sLeft = sLeft & Left(sRight, ptr - 1) & dst
sRight = Mid(sRight, ptr + lSrc)
ptr = InStr(sRight, src)
Loop
End If
strReplace = sLeft + sRight
End Function
If you want to split strings by JavaScript with Netscape Navigator 3.0 (NN3), you can use split() method. But with Microsoft Internet Explorer 3.xx (MSIE3), you cannot use it. Then try to use strSplit() function (follows). This function works both with NN3 and with MSIE3. strSplit() requires string argument src as a source, and a numeral argument pos as an index of output string and a string argument sep as a separator (delimiter). And it returns separated string that index is sep. sep is available from 0 to N-1 when src is separeted to N strings in amount. When string sep is not found in string src or when number pos is above amount of separated words, return value becomes "null".
/*
* split() for Internet Explorer 3.xx
* and for Netscape Navigator/Communicator
* written by Seiji Fujita
*/
function strSplit(src , sep , pos) {
var strWord = null;
var prePtr = 0;
var postPtr = 0;
var i = 0;
var flag = false;
if (sep != '') {
while((prePtr < src.length) && (i <= pos)) {
postPtr = src.indexOf(sep, prePtr);
if (postPtr >= 0) {
strWord = src.substring(prePtr , postPtr);
prePtr = postPtr + sep.length;
} else {
if ((i > 0) && (flag == false)) {
strWord = src.substring(prePtr , src.length);
} else {
strWord = null;
}
flag = true;
}
i++;
}
if (i <= pos) {
strWord = null;
}
return strWord;
} else {
return null;
}
}
var vString = "A Quick brown fox jumps over the lazy dog."; var vStr4th = strSplit(vString, " ", 3); var vStr7th = strSplit(vString, " ", 6); var vStr9th = strSplit(strSplit(vString, " ", 8),".", 0); var vStr10th = strSplit(vString, " ", 9);
A value of vStr4th becomes "fox" and a value of vStr7th becomes "the" and a value of vStr9th becomes "dog" and a value of vStr10th becomes "null".
When you split string by strSplit() with same string as src and same sapearator (delimiter) as sep, it took useless time. This function strSplitG() outputs separated words to global array SplitWord, it makes calculating time short until splitting by strSplitG() with another string or with another separator (* But if you need to change src or sep every time to call function, strSplit() may be fast). This function needs to be prepared array SplitWord in parent function, and it's element number needs to be larger than number of separable words.
This function returns amount of separated words (from 0). Return value equal 0 (zero) means that string sep is not found in string src, and the value of SplitWord[0]..SplitWord[NUM-1] becomes "null". Set parameter notfound = false.
** If you want to be returned SplitWord[0]=src when return value equal 0 (means src does not contain sep), set parameter notfound = true.
Return value equal -1 means that number of maximum value is not enough for amount of separable words (separable number > NUM + 1), and the value of SplitWord[0]..SplitWord[NUM-1] signs right separated strings, but you cannot get strings that should be separated originally as SplitWord[NUM] or SplitWord[NUM+x]...
This function works both with NN3 and with MSIE3.
/*
* split() for Internet Explorer 3.xx
* and for Netscape Navigator/Communicator
* written by Seiji Fujita
*
* Need to declare as var SplitWord = new Array(NUM); in parent function().
* NUM: set some integer. (enought larger than maximum expected)
*
* (If you want to use SplitWord as global array,
* replace declare part with one of followings.
*
* function strSplitG(src, sep, notfound) {
*
* notfound = false
* When return value = 0 (means not found sep in src), SplitWord[0] = null
* notfound = true
* When return value = 0 (means not found sep in src), SplitWord[0] = src
*/
function strSplitG(src, sep, SplitWord, notfound) {
var prePtr = 0.0;
var postPtr = 0.0;
var flag = false;
for (var i=0; i < NUM; i++) {
SplitWord[i] = null;
}
if (sep != '') {
i = 0;
while((prePtr < src.length) && (flag == false) && (i < NUM)) {
postPtr = src.indexOf(sep, prePtr);
if (postPtr >= 0) {
SplitWord[i] = src.substring(prePtr, postPtr);
prePtr = postPtr + sep.length;
} else {
if ((i > 0) && (flag == false)) {
SplitWord[i] = src.substring(prePtr, src.length);
prePtr = src.length + 1;
}
flag = true;
}
i++;
}
if ((src.indexOf(sep, prePtr) >= 0) && (i >= NUM)) {
return -1;
} else {
if (i == 1) { //or if ((i ==1) && (SplitWord[0] == null))
if (notfound) {
SplitWord[0] = src;
}
return 0;
} else {
return i;
}
}
} else {
return 0;
}
}
var NUM = 10; var vWord = new Array(NUM); var vString = "A Quick brown fox jumps over the lazy dog."; var vCount = strSplitG(vString, " ", vWord, false); var vStr4th = vWord[3]; var vStr7th = vWord[6]; var vStr9th = vWord[8]; var vStr20th = vWord[19];
A value of vCount becomes "9" and a value of vStr4th becomes "fox" and a value of vStr7th becomes "the" and a value of vStr9th becomes "dog." and a value of vStr20th becomes "null".
* When you set vWord's parameter that larger than NUM, return value is undefined (Example: when NUM=10, vWord[20] = undefined)
If you want to change numeral to string by JavaScript with Netscape Navigator 3.0 (NN3), you can use toString() method. But with Microsoft Internet Explorer 3.xx (MSIE3), you cannot use it. Then try to use toStr() function (follows). This function works both with NN3 and with MSIE3. toStr() requires an integral numeral argument vNum as an integer, and returns an equivalent string. This sample has no error processes whether vNum is a number or not. If you need an error correction, add it by yourself.
/*
* toString() for Internet Explorer 3.xx
* and for Netscape Navigator/Communicator
* written by Seiji Fujita
*/
function toStr(vNum) {
var vRef = "0123456789";
var vtmpStr = "";
var vtmpNum = 0;
var vMinus = false;
if (vNum < 0) {
vMinus = true;
vNum = -vNum;
}
var vlen = Math.floor( Math.log(vNum) / Math.log(10) ) + 1;
for ( i = 1; i <= vlen; i++ ) {
vtmpNum = vNum % 10;
vNum = Math.floor(vNum / 10);
vtmpStr = vRef.charAt(vtmpNum) + vtmpStr;
}
if (vMinus)
vtmpStr = "-" + vtmpStr;
return vtmpStr;
}
var vNum1 = 12; var vNum2 = 50; var vAdd1 = vNum1 + vNum2; var vAdd2 = toStr(vNum1) + toStr(vNum2);
A vAdd1's value becomes 62 (numeral) and a vAdd2's value becomes "1250" (string).
This is an extension of toStr() for any radix format (from 2 to 36). This function works both with NN3 and with MSIE3. radix should be an integer such as "10" as decimal or "0x0a" as hexadecimal or "012" as octal. vNum should be an integer. If you give a float value to vNum, it will be fixed to as an integer, but its result is not guaranteed. This sample has no error processes whether vNum is a number or not, or whether radix is an integer or not, and so on. If you need an error correction, add it by yourself.
Note:Output string has no mark that shows its radix such as prefix "0x". So if you change a decimal number "255" to hexadecimal format, output value looks as "ff" instead of "0xff".
/*
* toString() for Internet Explorer 3.xx
* and for Netscape Navigator/Communicator
* written by Seiji Fujita
*/
function toStrExt(vNum, radix) {
var vRef = "0123456789abcdefghijklmnopqrstuvwxyz";
var vtmpStr = "";
var vtmpNum = 0;
var vMinus = false;
if (vNum < 0) {
vMinus = true;
vNum = -vNum;
}
var vlen = Math.floor( Math.log(vNum) / Math.log(radix) ) + 1;
for ( i = 1; i <= vlen; i++ ) {
vtmpNum = vNum % radix;
vNum = Math.floor(vNum / radix);
vtmpStr = vRef.charAt(vtmpNum) + vtmpStr;
}
if (vMinus)
vtmpStr = "-" + vtmpStr;
return vtmpStr;
}
var vNum1 = 12; var vNum2 = 50; var vAdd1 = vNum1 + vNum2; var vAdd2 = toStrExt(vNum1,8) + toStrExt(vNum2,0x10);
A vAdd1's value becomes 62 (numeral) and a vAdd2's value becomes "1432" (string).
If you want to judge whether a string argument is a number (decimal or hexadecimal or octal) or not by JavaScript, you can use parseFloat() or parseInt(). But their false value is different between with Netscape Navigator 3.0 (NN3) and with NN2, such as a special string "NaN" with NN3 and numeral 0 (zero) with NN2. Their false value with Microsoft Intenet Explorer 3.xx (MSIE3) is 0, same as with NN2. So you cannot use same function to judge argument. Then try to use isNum() function (follows). This function works with NN2, NN3 and MSIE3. isNum() requires a string argument vInStr as a source, and returns a boolean value with true or false as judge whether vInStr can be estimated number (decimal or hexadecimal or octal) or not.
This function ignores 1byte spaces in the front/rear of string by trim function mentioned later, so you have to declare ltrim, rtrim, trim to use isNum function.
[Sep 9, 2003] Revised for missusing such as inputting numeric or spaces into vInStr rather than numeral string.
/*
* isNum() to judge string as if decimal / hexadecimal / ocatal or not
* for Netscape Navigator/Communicator and Microsoft Internet Explorer
* written by Seiji Fujita
* return value is true or false as boolean
*/
function isNum(vInStr) {
var vRefDec = "0123456789";
var vRefOct = "01234567";
var vRefHex = "0123456789abcdefABCDEF";
var vRefSgn = "+-";
var vRefExp = "eE";
var judge = true;
var vExp = false;
var vExpSgn = false;
var vPeriod = false;
var vIn = "";
vIn = vIn + vInStr;
vIn = trim(vIn);
var vlen = vIn.length;
if ( vRefSgn.indexOf(vIn.charAt(0)) >= 0 ) {
vIn = vIn.substring(1,vlen);
vlen = vIn.length;
}
var i = 0;
isHex = vIn.indexOf("0x");
if (vlen == 0) {
judge = false;
} else if ( isHex >= 0 ) {
if ( isHex >= 1 )
judge = false;
else {
vIn = vIn.substring(2,vlen);
vlen = vIn.length;
}
while ( (judge) && (i < vlen) ) {
if ( vRefHex.indexOf(vIn.charAt(i) ) < 0 )
judge = false;
i++;
}
} else if ( (vIn.charAt(0) == "0")
&& ( vIn.charAt(1) != "." ) ) {
while ((judge) && (i < vlen)) {
if (vRefOct.indexOf(vIn.charAt(i)) < 0)
judge = false;
i++;
}
} else {
while ( (judge) && (i < vlen) ) {
if ( vRefDec.indexOf(vIn.charAt(i)) < 0 ) {
if ( vRefSgn.indexOf(vIn.charAt(i) ) >= 0 )
if ((i <= 1) || (i == vlen-1))
judge = false;
else if ( !(vExpSgn) && (vExp) && (i >= 2) )
vExpSgn = true;
else
judge = false;
else if ( vIn.charAt(i) == "." )
if ( !(vPeriod) && !(vExp) && (i < vlen-1) )
vPeriod = true;
else
judge = false;
else if ( !(vExp) && (i > 0) && (i < vlen-1)
&& (vRefExp.indexOf(vIn.charAt(i)) >= 0) )
vExp = true;
else
judge = false;
}
i++;
}
}
return judge;
}
isNum(" -1500") // true
isNum("-15.00") // true
isNum(" +15.00 ") // true [*]
isNum(" +15.00-") // false
isNum(" +15.00e+3") // true [*]
isNum(" 15.00e5") // true
isNum("15.00e-15") // true
isNum(" +15.00e+35") // true [*]
isNum(" 15.00e3.5") // false
isNum(" +15.00e+3.5") // false
isNum(" -0xfe+a") // false
isNum(" -0xfega") // false
isNum(" +0x3aea") // true [*]
isNum(" +0x3AeA") // true [*]
isNum(" +0x3a.ea") // false
If you want to evaluate isNum(), go to [Evaluation Page].
Numeral strings with "true [*1]" in examples & results of 3.(1) are estimated as a number, but each of them causes error, when it use as an argument of eval() function with NN3 (or maybe NN2), because of prefixed "+"(plus) sign. I don't know why. With MSIE, eval() works right. So before using eval(), you should remove prefixed "+"(plus) sign. Because it is wastes your codes and times to check whether your visitor's browser is NN3 or not whenever you use eval() function. Following sample function is to remove prefixed "+"(plus) sign for NN2/NN3 and MSIE3. eval() ignores 1byte spaces in the front/rear of string, but this dePlusSign function removes them, by using trim function mentioned later, so you have to declare ltrim, rtrim, trim to use dePlusSign function.
* Using Netscape Navigator 4.78, you can get right answers when you substitute numeral strings with plus sign to eval(). That's the same with Opera 7.11.
/*
* function to remove prefixed "+"(plus) sign
* written by Seiji Fujita
*/
function dePlusSign(vInStr) {
var vlen = vInStr.length;
vInStr = trim(vInStr);
if (vInStr.charAt(0) == "+")
vInStr = vInStr.substring(1,vlen);
return vInStr;
}
var a = eval(dePlusSign("+3.55e5"));
If you want to evaluate dePlusSign(), go to [Evaluation Page].
This function is to transfer integer (from 1 to 702) to two digit alphabetical number (from "A" to "ZZ"); just like column index of MS-Excel etc such as series of A,B,C,...,Z,AA,AB,...,ZZ. At first sight, output "number" looks as 27 radix, but it isn't. Because this output string is "AA" for 27 instead of "A_". So this two digit alphabetical number expresses 702 at the most instead of 728 by 27 radix.
Visual BASIC for Application version of this function is above.
/* Function for integer(1-702) to two digit alphabetical "number"
* written by Seiji Fujita
* Output alphabetical numbers are A,B,C...,Z,AA,AB,...,ZZ.
* Notice: output is not 27 radix.
*/
function Num2Alpha(num) {
var upper = 0;
var lower = 0;
var Ref = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
var tmp = 0;
if ((num <= 0) || (num > 702))
return "ERR";
upper = Math.floor( (num - 1) / 26);
lower = (num - 1 ) % 26 + 1;
if (upper > 0)
tmp = Ref.charAt(upper - 1) + Ref.charAt(lower - 1);
else
tmp = Ref.charAt(lower - 1);
return tmp;
}
This is almost the same as (1) except output string has not "I" and "O". This rule may use in product numbering to avoid confusion 1 with I, or 0 with O. Output alphabetical numbers are A,B,...,H,J,...,N,P,...,Z,AA,AB,...,AH,AJ,...,AN,AP,...AZ,...,HZ,JA,...,NZ,PA,...PZ,...,ZZ. Output is not 25 radix.
/* Function for integer(1-600) to two digit alphabetical "number"
* written by Seiji Fujita
* Output alphabetical numbers are A,B,...,H,J,...,N,P,...,Z,
* AA,AB,...,AH,AJ,...,AN,AP,...AZ,...,HZ,JA,...,NZ,PA,...PZ,...,ZZ
* Notice: output is not 25 radix.
*/
function Num2Alpha2(num) {
var upper = 0;
var lower = 0;
var Ref = "ABCDEFGHJKLMNPQRSTUVWXYZ";
var tmp = 0;
if ((num <= 0) || (num > 600))
return "ERR";
upper = Math.floor( (num - 1) / 24);
lower = (num - 1 ) % 24 + 1;
if (upper > 0)
tmp = Ref.charAt(upper - 1) + Ref.charAt(lower - 1);
else
tmp = Ref.charAt(lower - 1);
return tmp;
}
/* function to remove spaces in front of string */
function ltrim(vInStr) {
var vlen = vInStr.length;
while (vInStr.charAt(0) == " ") {
vInStr = vInStr.substring(1,vlen);
vlen = vInStr.length;
}
return vInStr;
}
/* function to remove spaces at the back of string */
function ltrim(vInStr) {
var vlen = vInStr.length;
while (vInStr.charAt(0) == " ") {
vInStr = vInStr.substring(1,vlen);
vlen = vInStr.length;
}
return vInStr;
}
This function uses ltrim, rtrim shown above, so you need declare these functions to use this function.
/* function to remove spaces in front of/ at the back of string
* written by Seiji Fujita
*/
function trim(vInStr) {
return ltrim(rtrim(vInStr));
}
This function uses trim shown above, so you need declare ltrim, rtrim and trim functions to use this function.
/* function to remove spaces in front of/ at the back of string
* and to shrink series of spaces within string into a space.
* written by Seiji Fujita
*/
function xtrim(vInStr) {
vInStr = trim(vInStr);
var i = 1;
while (i < vInStr.length) {
if ((vInStr.charAt(i) == " ") && (vInStr.charAt(i+1) == " ")) {
vInStr = vInStr.substring(0, i) + " " + vInStr.substring(i+2, vInStr.length);
} else {
i++;
}
}
return vInStr;
}
If you manage 2byte spaces in string, check xtrim for 2byte code.
If you want to replace string by JavaScript with Microsoft Internet Explorer 4.xx (MSIE4) or Netscape Navigator 4.xx (NN4) or later version, you can use replace() method. But with older web browser such as MSIE3.xx or NN3.xx, you cannot use it. Then try to use strReplace() function (follows). This function replaces string ssrc in strOrg by string sdest.
When sdest is empty, this function work as delete ssrc in strOrg.
When gflag is true, replace every string matched ssrc, when gflag is false, replace first string matched ssrc only.
When iflag is true, ignore case distinctions in both "ssrc" and "strOrg".
If ssrc is not found in strOrg, return value is strOrg as it is. This function consider not to replace recursively, such as replacement string with same string (replace "a" by "a" or by "abc")
/* replace string function
* written by Seiji Fujita
*
* Replace string "ssrc" in strOrg by "sdest".
* If ssrc is not found in strOrg, return value is strOrg as it is.
* gflag = false : replace first string matched "ssrc" only.
* = true : replace every string matched "ssrc".
* iflag = true : ignore case distinctions in both "ssrc" and "strOrg".
*/
function strReplace(strOrg, ssrc, sdest, gflag, iflag) {
var slOrg = strOrg.length;
var slSrc = ssrc.length;
var sleft = "";
var sright = strOrg;
if (iflag) {
var sisrc = ssrc.toLowerCase();
var pos = strOrg.toLowerCase().indexOf(sisrc);
if ((slOrg > 0) && (slSrc > 0) && (pos >= 0)) {
while(pos >= 0) {
sleft = sleft + sright.substring(0, pos) + sdest;
sright = sright.substring(pos + slSrc, slOrg);
slOrg = sright.length;
pos = sright.toLowerCase().indexOf(sisrc);
if (!gflag) {
pos = -1;
}
}
}
} else {
var pos = strOrg.indexOf(ssrc);
if ((slOrg > 0) && (slSrc > 0) && (pos >= 0)) {
while(pos >= 0) {
sleft = sleft + sright.substring(0, pos) + sdest;
sright = sright.substring(pos + slSrc, slOrg);
slOrg = sright.length;
pos = sright.indexOf(ssrc);
if (!gflag) {
pos = -1;
}
}
}
}
return sleft + sright;
}
If you want to evaluate strReplace(), go to [Evaluation Page].
* If you don't consider older web browser, you can write replacement function with (a) string.split() method and string.join() method, or (b) regular expression object RegExp() and string.replace() method.