I want to convert a list into range.
a = ['Eth1/1', 'Eth1/2', 'Eth1/3', 'Eth1/4', 'Eth1/5', 'Eth1/6', 'Eth1/7', 'Eth1/8', 'Eth1/9', 'Eth1/10','Eth2/1', 'Eth2/2', 'Eth2/3', 'Eth2/4', 'Eth2/5', 'Eth2/6','Eth3/1', 'Eth3/2', 'Eth3/3', 'Eth3/4', 'Eth3/5', 'Eth3/6','Eth4/1', 'Eth4/2', 'Eth4/3', 'Eth4/4', 'Eth4/5', 'Eth4/6']
what i am trying :
fp = open('mode.txt' , 'w+')
for i in a:
fp.write('confi ' + i + '\n mode \n')
what i am looking for :
confi Eth1/1-5
mode
confi Eth1/6-10
mode
confi Eth2/1-6
mode
confi Eth3/1-6
mode
confi Eth4/1-6
mode
Any idea how to do this ?
You could create a loop that checks the current element as the start. If it starts with Eth1 then get the 4th element after as the end. Otherwise, keep the starting Eth_, iterate through the list until you get the last Eth_ element or until the list end. Assign the last element as the end.
a = ['Eth1/1', 'Eth1/2', 'Eth1/3', 'Eth1/4', 'Eth1/5', 'Eth1/6', 'Eth1/7', 'Eth1/8', 'Eth1/9', 'Eth1/10','Eth2/1', 'Eth2/2', 'Eth2/3', 'Eth2/4', 'Eth2/5', 'Eth2/6','Eth3/1', 'Eth3/2', 'Eth3/3', 'Eth3/4', 'Eth3/5', 'Eth3/6','Eth4/1', 'Eth4/2', 'Eth4/3', 'Eth4/4', 'Eth4/5', 'Eth4/6']
i = 0
while i < len(a):
start = a[i].split('/')
if (start[0] == 'Eth1'):
i += 5
else:
key = start[0]
i += 1
while i < len(a) and a[i].split('/')[0] == key:
i += 1
end = a[i-1].split('/')
print('confi ' + start[0] + '/' + start[1] + '-' + end[1] + '\n mode\n')
Related
I've implemented the solution at
Google Sheets multiple search and replace from a list for a similar issue.
I'm using the script
function preg_quote( str ) {
// http://kevin.vanzonneveld.net
// + original by: booeyOH
// + improved by: Ates Goral (http://magnetiq.com)
// + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
// + bugfixed by: Onno Marsman
// * example 1: preg_quote("$40");
// * returns 1: '\$40'
// * example 2: preg_quote("*RRRING* Hello?");
// * returns 2: '\*RRRING\* Hello\?'
// * example 3: preg_quote("\\.+*?[^]$(){}=!<>|:");
// * returns 3: '\\\.\+\*\?\[\^\]\$\(\)\{\}\=\!\<\>\|\:'
return (str+'').replace(/([\\\.\+\*\?\[\^\]\$\(\)\{\}\=\!\<\>\|\:])/g, "\\$1");
}
function ARRAYREPLACE(input,fromList,toList,caseSensitive){
/* default behavior it is not case sensitive */
if( caseSensitive == undefined ){
caseSensitive = false;
}
/* if the from list it is not a list, become a list */
if( typeof fromList != "object" ) {
fromList = [ fromList ];
}
/* if the to list it is not a list, become a list */
if( typeof toList != "object" ) {
toList = [ toList ];
}
/* force the input be a string */
var result = input.toString();
/* iterates using the max size */
var bigger = Math.max( fromList.length, toList.length) ;
/* defines the words separators */
var arrWordSeparator = [ ".", ",", ";", " " ];
/* interate into the lists */
for(var i = 0; i < bigger; i++ ) {
/* get the word that should be replaced */
var fromValue = fromList[ ( i % ( fromList.length ) ) ]
/* get the new word that should replace */
var toValue = toList[ ( i % ( toList.length ) ) ]
/* do not replace undefined */
if ( fromValue == undefined ) {
continue;
}
if ( toValue == undefined ) {
toValue = "";
}
/* apply case sensitive rule */
var caseRule = "g";
if( !caseSensitive ) {
/* make the regex case insensitive */
caseRule = "gi";
}
/* for each end word char, make the replacement and update the result */
for ( var j = 0; j < arrWordSeparator.length; j++ ) {
/* from value being the first word of the string */
result = result.replace( new RegExp( "^(" + preg_quote( fromValue + arrWordSeparator[ j ] ) + ")" , caseRule ), toValue + arrWordSeparator[ j ] );
/* from value being the last word of the string */
result = result.replace( new RegExp( "(" + preg_quote( arrWordSeparator[ j ] + fromValue ) + ")$" , caseRule ), arrWordSeparator[ j ] + toValue );
/* from value in the middle of the string between two word separators */
for ( var k = 0; k < arrWordSeparator.length; k++ ) {
result = result.replace(
new RegExp(
"(" + preg_quote( arrWordSeparator[ j ] + fromValue + arrWordSeparator[ k ] ) + ")" ,
caseRule
),
/* need to keep the same word separators */
arrWordSeparator[ j ] + toValue + arrWordSeparator[ k ]
);
}
}
/* from value it is the only thing in the string */
result = result.replace( new RegExp( "^(" + preg_quote( fromValue ) + ")$" , caseRule ), toValue );
}
/* return the new result */
return result;
}
An example input is;
"
DETAILS
halter neck style sleeveless detachable
waist tie gathered tiered skirt panels invisible
back zip back neck opening with button close
unlined SIZING
model is 170cm and wears a size 8 garment flat
measurements: size 8 length - 139cm, waist - 33cm,
bust - 43cm size 10 length - 141cm, waist - 35cm, bust -
45cm size 12 length - 143cm, waist - 37cm, bust - 47cm
size 14 length - 145cm, waist - 38cm, bust - 48cm
model stats: bust - 76cm, waist - 57cm, hips - 91cm
GARMENT CARE material - rayon
cold hand wash separately
"
and the replacement list is at;
https://docs.google.com/spreadsheets/d/1MxaZ1Jki1fnVw6jfFllur2BpPN6-6b6fAmLSKQniG-8/edit#gid=0
However my results are only showing a conversion of some of the strings. Below is the output;
"
DETAILS
halter neck style sleeveless detachable
waist tie gathered tiered skirt panels invisible
back zip back neck opening with button close
unlined SIZING
model is 5' 6"" and wears a size 8 garment flat
measurements: size 8 length - 54.5"", waist - 13"",
bust - 43cm size 10 length - 55.5"", waist - 14"", bust -
45cm size 12 length - 56.5"", waist - 14.5"", bust -
47cm size 14 length - 57"", waist - 15"", bust - 48cm
model stats: bust - 30"", waist - 22.5"", hips - 91cm
GARMENT CARE
material - rayon cold hand wash separately
"
The third instance of the dimensions on each line is being ignored, as are the sizes entirely. Could anyone tell me if the script limited to a certain number of replacements, or any changes I should make to replace the sizes? Thanks in advance.
After testing the code the problems seems to be with the values at the end of a line. If you have your input defined as a multi-line JavaScript string make sure that you leave a space after those values.
var input = "\
DETAILS\
\
halter neck style\
sleeveless\
detachable waist tie\
gathered tiered skirt panels\
invisible back zip\
back neck opening with button close\
unlined\
SIZING\
\
model is 170cm and wears a size 8\
garment flat measurements:\
size 8 length - 139cm, waist - 33cm, bust - 43cm \ //Notice the space after "cm"
size 10 length - 141cm, waist - 35cm, bust - 45cm \
size 12 length - 143cm, waist - 37cm, bust - 47cm \
size 14 length - 145cm, waist - 38cm, bust - 48cm \
model stats: bust - 76cm, waist - 57cm, hips - 91cm \
GARMENT CARE\
\
material - rayon\
cold hand wash separately\
";
If you are reading this input through a file, probably the problem is related to a new line (\n) or a carriage return (\r), I would add those values in the arrWordSeparator variable to take care of multi-line inputs. So it would look something similar to this:
/* defines the words separators */
var arrWordSeparator = [ ".", ",", ";", " ", "\n", "\r" ];
I have a string with characters repeated. My Job is to find starting Index and ending index of each unique characters in that string. Below is my code.
import re
x = "aaabbbbcc"
xs = set(x)
for item in xs:
mo = re.search(item,x)
flag = item
m = mo.start()
n = mo.end()
print(flag,m,n)
Output :
a 0 1
b 3 4
c 7 8
Here the end index of the characters are not correct. I understand why it's happening but how can I pass the character to be matched dynamically to the regex search function. For instance if I hardcode the character in the search function it provides the desired output
x = 'aabbbbccc'
xs = set(x)
mo = re.search("[b]+",x)
flag = item
m = mo.start()
n = mo.end()
print(flag,m,n)
output:
b 2 5
The above function is providing correct result but here I can't pass the characters to be matched dynamically.
It will be really a help if someone can let me know how to achieve this any hint will also do. Thanks in advance
String literal formatting to the rescue:
import re
x = "aaabbbbcc"
xs = set(x)
for item in xs:
# for patterns better use raw strings - and format the letter into it
mo = re.search(fr"{item}+",x) # fr and rf work both :) its a raw formatted literal
flag = item
m = mo.start()
n = mo.end()
print(flag,m,n) # fix upper limit by n-1
Output:
a 0 3 # you do see that the upper limit is off by 1?
b 3 7 # see above for fix
c 7 9
Your pattern does not need the [] around the letter - you are matching just one anyhow.
Without regex1:
x = "aaabbbbcc"
last_ch = x[0]
start_idx = 0
# process the remainder
for idx,ch in enumerate(x[1:],1):
if last_ch == ch:
continue
else:
print(last_ch,start_idx, idx-1)
last_ch = ch
start_idx = idx
print(ch,start_idx,idx)
output:
a 0 2 # not off by 1
b 3 6
c 7 8
1RegEx: And now you have 2 problems...
Looking at the output, I'm guessing that another option would be,
import re
x = "aaabbbbcc"
xs = re.findall(r"((.)\2*)", x)
start = 0
output = ''
for item in xs:
end = start + len(item[0])
output += (f"{item[1]} {start} {end}\n")
start = end
print(output)
Output
a 0 3
b 3 7
c 7 9
I think it'll be in the Order of N, you can likely benchmark it though, if you like.
import re, time
timer_on = time.time()
for i in range(10000000):
x = "aabbbbccc"
xs = re.findall(r"((.)\2*)", x)
start = 0
output = ''
for item in xs:
end = start + len(item[0])
output += (f"{item[1]} {start} {end}\n")
start = end
timer_off = time.time()
timer_total = timer_off - timer_on
print(timer_total)
So I am trying to split characters a certain way.
If I provide this string:
text (text (adsf (asdfasdfjkl) asdfjlkasdjf) stuff) (morestuff stuff)
I want it to split it into:
['text', '(text (adsf (asdfasdfjkl) asdfjlkasdjf) stuff)', '(morestuff stuff)']
Code I had:
def pair_char(left, right, start, text, exclusive=False, verbose=False):
package = []
for e, c in enumerate(text):
left_c = right_c = 0
if text[e] == left:
left_c += 1
marker = start = e
while text[marker+1] != right or left_c > right_c:
marker += 1
if verbose:
print left_c, right_c, text[marker], left, right, text[marker]==left, text[marker]==right
if marker+1 >= len(text):
break
if text[marker] == left_c:
print "left_c"
left_c += 1
if text[marker] == right_c:
print "right_c"
right_c += 1
end = marker
if exclusive:
package.append(text[start+1:end])
else:
package.append(text[start:end+1])
e = end
package = "".join(package)
return package
Any suggestions?
In a question I am asked to find if the given string s contains two non-overlapping substrings "AB" and "BA" (the substrings can go in any order).
I have already solved this question but since I am learning Z-algorithm.Can anyone help me in that ?
I know how to find number of occurrence of a pattern in a text(by appending P and T)but I am not getting any idea how to solve this using Z algorithm ?
To find if T contains P with Z-algorithm:
S = P + '#' + T //extra char not occurring in strings
for i in 0..Length(T) - 1 do
if Z[i + Length(P) + 1] = Length(P) then
P contains T in ith position
To find if T contains both 'AB' and 'BA' without overlapping:
Sab = 'AB#' + T
Sba = 'BA#' + T
Build Zab and Zba arrays with Z-algo
PosAB_Last = Length(T) + 10 //just big value
PosAB_Prev = PosAB_Last
PosBA_Last = PosAB_Last
PosBA_Prev = PosAB_Last
for i in 0..Length(T) - 1 do
if Zab[i + 3] = 2 then
PosAB_Prev = PosAB_Last //keep two last positions of AB in text
PosAB_Last = i
//it is enough to compare positions with two last occurences of 'BA '
//so algo is linear
if (i - PosBA_Last > 1) or (i - PosBA_Prev > 1) then
Success
else
if Zba[i + 3] = 2 then
PosBA_Prev = PosBA_Last
PosBA_Last = i
if (i - PosAB_Last > 1) or (i - PosAB_Prev > 1) then
Success
I have a column where each cell has a string of digits, ?, -, and digits in parentheses/brackets/curly brackets. A good example would be something like the following:
3????0{1012}?121-2[101]--01221111(01)1
How do I separate the string into different cells by characters, where a 'character' in this case refers to any number, ?, -, and value within the parentheses/brackets/curly brackets (including said parentheses/brackets/curly brackets)?
In essence, the string above would turn into the following (spaced apart to denote a separate cell):
3 ? ? ? ? 0 {1012} ? 1 2 1 - 2 [101] - - 0 1 2 2 1 1 1 1 (01) 1
The amount of numbers within the parentheses/brackets/curly brackets vary. There are no letters in any of the strings.
Here you are!
RegEx method:
Sub Test_RegEx()
Dim s, col, m
s = "3????0{1012}?121-2[101]--01221111(01)1"
Set col = CreateObject("Scripting.Dictionary")
With CreateObject("VBScript.RegExp")
.Global = True
.Pattern = "(?:\d|-|\?|\(\d+\)|\[\d+\]|\{\d+\})"
For Each m In .Execute(s)
col(col.Count) = m
Next
End With
MsgBox Join(col.items) ' 3 ? ? ? ? 0 {1012} ? 1 2 1 - 2 [101] - - 0 1 2 2 1 1 1 1 (01) 1
End Sub
Loop method:
Sub Test_Loop()
Dim s, col, q, t, k, i
s = "3????0{1012}?121-2[101]--01221111(01)1"
Set col = CreateObject("Scripting.Dictionary")
q = "_"
t = True
k = 0
For i = 1 To Len(s)
t = (t Or InStr(1, ")]}", q) > 0) And InStr(1, "([{", q) = 0
q = Mid(s, i, 1)
If t Then k = k + 1
col(k) = col(k) & q
Next
MsgBox Join(col.items) ' 3 ? ? ? ? 0 {1012} ? 1 2 1 - 2 [101] - - 0 1 2 2 1 1 1 1 (01) 1
End Sub
Something else to look at :)
Sub test()
'String to parse through
Dim aStr As String
'final string to print
Dim finalString As String
aStr = "3????0{1012}?121-2[101]--01221111(01)1"
'Loop through string
For i = 1 To Len(aStr)
'The character to look at
char = Mid(aStr, i, 1)
'Check if the character is an opening brace, curly brace, or parenthesis
Dim result As String
Select Case char
Case "["
result = loop_until_end(Mid(aStr, i + 1), "]")
i = i + Len(result)
result = char & result
Case "("
result = loop_until_end(Mid(aStr, i + 1), ")")
i = i + Len(result)
result = char & result
Case "{"
result = loop_until_end(Mid(aStr, i + 1), "}")
i = i + Len(result)
result = char & result
Case Else
result = Mid(aStr, i, 1)
End Select
finalString = finalString & result & " "
Next
Debug.Print (finalString)
End Sub
'Loops through and concatenate to a final string until the end_char is found
'Returns a substring starting from the character after
Function loop_until_end(aStr, end_char)
idx = 1
If (Len(aStr) <= 1) Then
loop_until_end = aStr
Else
char = Mid(aStr, idx, 1)
Do Until (char = end_char)
idx = idx + 1
char = Mid(aStr, idx, 1)
Loop
End If
loop_until_end = Mid(aStr, 1, idx)
End Function
Assuming the data is in column A starting in row 1 and that you want the results start in column B and going right for each row of data in column A, here is alternate method using only worksheet formulas.
In cell B1 use this formula:
=IF(OR(LEFT(A1,1)={"(","[","{"}),LEFT(A1,MIN(FIND({")","]","}"},A1&")]}"))),IFERROR(--LEFT(A1,1),LEFT(A1,1)))
In cell C1 use this formula:
=IF(OR(MID($A1,SUMPRODUCT(LEN($B1:B1))+1,1)={"(","[","{"}),MID($A1,SUMPRODUCT(LEN($B1:B1))+1,MIN(FIND({")","]","}"},$A1&")]}",SUMPRODUCT(LEN($B1:B1))+1))-SUMPRODUCT(LEN($B1:B1))),IFERROR(--MID($A1,SUMPRODUCT(LEN($B1:B1))+1,1),MID($A1,SUMPRODUCT(LEN($B1:B1))+1,1)))
Copy the C1 formula right until it starts giving you blanks (there are no more items left to split out from the string in the A cell). In your example, need to copy it right to column AA. Then you can copy the formulas down for the rest of your Column A data.