// Removes the first parts of a string that match the pattern. func removePattern(str string, pattern *regexp.Regexp) string { found := pattern.Find([]byte(str)) if found != nil { return strings.Replace(str, string(found), "", 1) } return str }
func (r *FetchResult) find(re *regexp.Regexp) (numbers []int) { numbers = make([]int, LOTTO_SIZE) lotto := re.Find(r.body) noExp := regexp.MustCompile(`\d+`) noBytes := noExp.FindAll(lotto, -1) for i := 0; i < len(noBytes); i++ { if no, err := strconv.Atoi(string(noBytes[i])); err == nil { numbers[i] = no } } return }
// Search finds all lines matching regexp. context is the number of context // lines to include before and after the match. func (g *Grep) Search(r *regexp.Regexp, context int) []Match { matches := make([]Match, 0) for i, l := range g.lines { m := r.Find(l) if m == nil { continue } matches = append(matches, Match{ LineNum: i + 1, Match: m, FullLine: l, ContextBefore: g.context(i-context, i), ContextAfter: g.context(i+1, i+1+context), }) } return matches }
func (s *SimpleScanner) Match(pattern string) ([]byte, Scanner) { var regc *regexp.Regexp var err error if pattern[0] != '^' { panic("match patterns must begin with `^`") } regc = s.patterns[pattern] if regc == nil { if regc, err = regexp.Compile(pattern); err == nil { s.patterns[pattern] = regc } else { panic(err.Error()) } } if token := regc.Find(s.buf[s.cursor:]); token != nil { s.cursor += len(token) return token, s } return nil, s }
func retrieve_urls(uri string, urlRegexp *regexp.Regexp) []string { urls := []string{} resp, err := http.Get(uri) if err != nil { return urls } defer resp.Body.Close() body, err := ioutil.ReadAll(resp.Body) lines := strings.Split(string(body), "\n") for _, v := range lines { matched, _ := regexp.MatchString("<a href=\"http", v) if matched { matchedurl := string(urlRegexp.Find([]byte(v))) matchedurl = fixUrl(matchedurl) visited[matchedurl]++ if visited[matchedurl] > 1 { continue } else { urls = append(urls, matchedurl) } } } return urls }
func (c *CssCompressor) performGeneralCleanup() { // This function does a lot, ok? var sb bytes.Buffer var previousIndex int var re *regexp.Regexp // Remove the spaces before the things that should not have spaces before them. // But, be careful not to turn "p :link {...}" into "p:link{...}" // Swap out any pseudo-class colons with the token, and then swap back. c.Css = RegexFindReplace(c.Css, "(^|\\})(([^\\{:])+:)+([^\\{]*\\{)", func(groups []string) string { s := groups[0] s = strings.Replace(s, ":", "___YUICSSMIN_PSEUDOCLASSCOLON___", -1) s = strings.Replace(s, "\\\\", "\\\\\\\\", -1) s = strings.Replace(s, "\\$", "\\\\\\$", -1) return s }) // Remove spaces before the things that should not have spaces before them. re, _ = regexp.Compile("\\s+([!{};:>+\\(\\)\\],])") c.Css = re.ReplaceAll(c.Css, []byte("$1")) // Restore spaces for !important c.Css = bytes.Replace(c.Css, []byte("!important"), []byte(" !important"), -1) // bring back the colon c.Css = bytes.Replace(c.Css, []byte("___YUICSSMIN_PSEUDOCLASSCOLON___"), []byte(":"), -1) // retain space for special IE6 cases c.Css = RegexFindReplace(c.Css, "(?i):first\\-(line|letter)(\\{|,)", func(groups []string) string { return strings.ToLower(":first-"+groups[1]) + " " + groups[2] }) // no space after the end of a preserved comment c.Css = bytes.Replace(c.Css, []byte("*/ "), []byte("*/"), -1) // If there are multiple @charset directives, push them to the top of the file. c.Css = RegexFindReplace(c.Css, "(?i)^(.*)(@charset)( \"[^\"]*\";)", func(groups []string) string { return strings.ToLower(groups[2]) + groups[3] + groups[1] }) // When all @charset are at the top, remove the second and after (as they are completely ignored). c.Css = RegexFindReplace(c.Css, "(?i)^((\\s*)(@charset)( [^;]+;\\s*))+", func(groups []string) string { return groups[2] + strings.ToLower(groups[3]) + groups[4] }) // lowercase some popular @directives c.Css = RegexFindReplace(c.Css, "(?i)@(charset|font-face|import|(?:-(?:atsc|khtml|moz|ms|o|wap|webkit)-)?keyframe|media|page|namespace)", func(groups []string) string { return "@" + strings.ToLower(groups[1]) }) // lowercase some more common pseudo-elements c.Css = RegexFindReplace(c.Css, "(?i):(active|after|before|checked|disabled|empty|enabled|first-(?:child|of-type)|focus|hover|last-(?:child|of-type)|link|only-(?:child|of-type)|root|:selection|target|visited)", func(groups []string) string { return ":" + strings.ToLower(groups[1]) }) // lowercase some more common functions c.Css = RegexFindReplace(c.Css, "(?i):(lang|not|nth-child|nth-last-child|nth-last-of-type|nth-of-type|(?:-(?:moz|webkit)-)?any)\\(", func(groups []string) string { return ":" + strings.ToLower(groups[1]) + "(" }) // lower case some common function that can be values // NOTE: rgb() isn't useful as we replace with #hex later, as well as and() is already done for us right after this c.Css = RegexFindReplace(c.Css, "(?i)([:,\\( ]\\s*)(attr|color-stop|from|rgba|to|url|(?:-(?:atsc|khtml|moz|ms|o|wap|webkit)-)?(?:calc|max|min|(?:repeating-)?(?:linear|radial)-gradient)|-webkit-gradient)", func(groups []string) string { return groups[1] + strings.ToLower(groups[2]) }) // Put the space back in some cases, to support stuff like // @media screen and (-webkit-min-device-pixel-ratio:0){ re, _ = regexp.Compile("(?i)\\band\\(") c.Css = re.ReplaceAll(c.Css, []byte("and (")) // Remove the spaces after the things that should not have spaces after them. re, _ = regexp.Compile("([!{}:;>+\\(\\[,])\\s+") c.Css = re.ReplaceAll(c.Css, []byte("$1")) // remove unnecessary semicolons re, _ = regexp.Compile(";+}") c.Css = re.ReplaceAll(c.Css, []byte("}")) // Replace 0(px,em,%) with 0. re, _ = regexp.Compile("(?i)(^|[^0-9])(?:0?\\.)?0(?:px|em|%|in|cm|mm|pc|pt|ex|deg|g?rad|m?s|k?hz)") c.Css = re.ReplaceAll(c.Css, []byte("${1}0")) // Replace 0 0 0 0; with 0. re, _ = regexp.Compile(":0 0 0 0(;|})") re2, _ := regexp.Compile(":0 0 0(;|})") re3, _ := regexp.Compile(":0 0(;|})") c.Css = re.ReplaceAll(c.Css, []byte(":0$1")) c.Css = re2.ReplaceAll(c.Css, []byte(":0$1")) c.Css = re3.ReplaceAll(c.Css, []byte(":0$1")) // Replace background-position:0; with background-position:0 0; // same for transform-origin c.Css = RegexFindReplace(c.Css, "(?i)(background-position|webkit-mask-position|transform-origin|webkit-transform-origin|moz-transform-origin|o-transform-origin|ms-transform-origin):0(;|})", func(groups []string) string { return strings.ToLower(groups[1]) + ":0 0" + groups[2] }) // Replace 0.6 to .6, but only when preceded by : or a white-space re, _ = regexp.Compile("(:|\\s)0+\\.(\\d+)") c.Css = re.ReplaceAll(c.Css, []byte("$1.$2")) // Shorten colors from rgb(51,102,153) to #336699 // This makes it more likely that it'll get further compressed in the next step. c.Css = RegexFindReplace(c.Css, "rgb\\s*\\(\\s*([0-9,\\s]+)\\s*\\)", func(groups []string) string { rgbcolors := strings.Split(groups[1], ",") var hexcolor bytes.Buffer hexcolor.WriteString("#") for _, colour := range rgbcolors { val, _ := strconv.Atoi(colour) if val < 16 { hexcolor.WriteString("0") } // If someone passes an RGB value that's too big to express in two characters, round down. // Probably should throw out a warning here, but generating valid CSS is a bigger concern. if val > 255 { val = 255 } hexcolor.WriteString(fmt.Sprintf("%x", val)) } return hexcolor.String() }) // Shorten colors from #AABBCC to #ABC. Note that we want to make sure // the color is not preceded by either ", " or =. Indeed, the property // filter: chroma(color="#FFFFFF"); // would become // filter: chroma(color="#FFF"); // which makes the filter break in IE. // We also want to make sure we're only compressing #AABBCC patterns inside { }, not id selectors ( #FAABAC {} ) // We also want to avoid compressing invalid values (e.g. #AABBCCD to #ABCD) sb.Reset() re, _ = regexp.Compile("(\\=\\s*?[\"']?)?" + "#([0-9a-fA-F])([0-9a-fA-F])([0-9a-fA-F])([0-9a-fA-F])([0-9a-fA-F])([0-9a-fA-F])" + "(:?\\}|[^0-9a-fA-F{][^{]*?\\})") previousIndex = 0 for match := re.Find(c.Css[previousIndex:]); match != nil; match = re.Find(c.Css[previousIndex:]) { index := re.FindIndex(c.Css[previousIndex:]) submatches := re.FindStringSubmatch(string(c.Css[previousIndex:])) submatchIndexes := re.FindSubmatchIndex(c.Css[previousIndex:]) sb.WriteString(string(c.Css[previousIndex : index[0]+len(c.Css[:previousIndex])])) //boolean isFilter = (m.group(1) != null && !"".equals(m.group(1))); // I hope the below is the equivalent of the above :P isFilter := submatches[1] != "" && submatchIndexes[1] != -1 if isFilter { // Restore, as is. Compression will break filters sb.WriteString(submatches[1] + "#" + submatches[2] + submatches[3] + submatches[4] + submatches[5] + submatches[6] + submatches[7]) } else { if strings.ToLower(submatches[2]) == strings.ToLower(submatches[3]) && strings.ToLower(submatches[4]) == strings.ToLower(submatches[5]) && strings.ToLower(submatches[6]) == strings.ToLower(submatches[7]) { // #AABBCC pattern sb.WriteString("#" + strings.ToLower(submatches[3]+submatches[5]+submatches[7])) } else { // Non-compressible color, restore, but lower case. sb.WriteString("#" + strings.ToLower(submatches[2]+submatches[3]+submatches[4]+submatches[5]+submatches[6]+submatches[7])) } } // The "+ 4" below is a crazy hack which will come back to haunt me later. // For now, it makes everything work 100%. previousIndex = submatchIndexes[7] + len(c.Css[:previousIndex]) + 4 } if previousIndex > 0 { sb.WriteString(string(c.Css[previousIndex:])) } if sb.Len() > 0 { c.Css = sb.Bytes() } // Save a few chars by utilizing short colour keywords. // https://github.com/yui/yuicompressor/commit/fe8cf35d3693910103d65bf465d33b0d602dcfea colours := map[string]string{ "#f00": "red", "#000080": "navy", "#808080": "gray", "#808000": "olive", "#800080": "purple", "#c0c0c0": "silver", "#008080": "teal", "#ffa500": "orange", "#800000": "maroon", } for k, v := range colours { re, _ = regexp.Compile("(:|\\s)" + k + "(;|})") c.Css = re.ReplaceAll(c.Css, []byte("${1}"+v+"${2}")) } // border: none -> border:0 c.Css = RegexFindReplace(c.Css, "(?i)(border|border-top|border-right|border-bottom|border-left|outline|background):none(;|})", func(groups []string) string { return strings.ToLower(groups[1]) + ":0" + groups[2] }) // shorter opacity IE filter re, _ = regexp.Compile("(?i)progid:DXImageTransform.Microsoft.Alpha\\(Opacity=") c.Css = re.ReplaceAll(c.Css, []byte("alpha(opacity=")) // Find a fraction that is used for Opera's -o-device-pixel-ratio query // Add token to add the "\" back in later re, _ = regexp.Compile("\\(([\\-A-Za-z]+):([0-9]+)\\/([0-9]+)\\)") c.Css = re.ReplaceAll(c.Css, []byte("(${1}:${2}___YUI_QUERY_FRACTION___${3})")) // Remove empty rules. re, _ = regexp.Compile("[^\\}\\{/;]+\\{\\}") c.Css = re.ReplaceAll(c.Css, []byte("")) // Add "\" back to fix Opera -o-device-pixel-ratio query c.Css = bytes.Replace(c.Css, []byte("___YUI_QUERY_FRACTION___"), []byte("/"), -1) }